Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ c4d2302e

History | View | Annotate | Download (210.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/fs.h>
81
#include "linux_loop.h"
82

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

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

    
95
//#define DEBUG
96

    
97
//#include <linux/msdos_fs.h>
98
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
99
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
100

    
101

    
102
#undef _syscall0
103
#undef _syscall1
104
#undef _syscall2
105
#undef _syscall3
106
#undef _syscall4
107
#undef _syscall5
108
#undef _syscall6
109

    
110
#define _syscall0(type,name)                \
111
static type name (void)                        \
112
{                                        \
113
        return syscall(__NR_##name);        \
114
}
115

    
116
#define _syscall1(type,name,type1,arg1)                \
117
static type name (type1 arg1)                        \
118
{                                                \
119
        return syscall(__NR_##name, arg1);        \
120
}
121

    
122
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
123
static type name (type1 arg1,type2 arg2)                \
124
{                                                        \
125
        return syscall(__NR_##name, arg1, arg2);        \
126
}
127

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

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

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

    
147

    
148
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
149
                  type5,arg5,type6,arg6)                                        \
150
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
151
                  type6 arg6)                                                        \
152
{                                                                                \
153
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
154
}
155

    
156

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

    
186
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
187
#define __NR__llseek __NR_lseek
188
#endif
189

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

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

    
251
#define COPY_UTSNAME_FIELD(dest, src) \
252
  do { \
253
      /* __NEW_UTS_LEN doesn't include terminating null */ \
254
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
255
      (dest)[__NEW_UTS_LEN] = '\0'; \
256
  } while (0)
257

    
258
static int sys_uname(struct new_utsname *buf)
259
{
260
  struct utsname uts_buf;
261

    
262
  if (uname(&uts_buf) < 0)
263
      return (-1);
264

    
265
  /*
266
   * Just in case these have some differences, we
267
   * translate utsname to new_utsname (which is the
268
   * struct linux kernel uses).
269
   */
270

    
271
  bzero(buf, sizeof (*buf));
272
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
273
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
274
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
275
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
276
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
277
#ifdef _GNU_SOURCE
278
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
279
#endif
280
  return (0);
281

    
282
#undef COPY_UTSNAME_FIELD
283
}
284

    
285
static int sys_getcwd1(char *buf, size_t size)
286
{
287
  if (getcwd(buf, size) == NULL) {
288
      /* getcwd() sets errno */
289
      return (-1);
290
  }
291
  return strlen(buf)+1;
292
}
293

    
294
#ifdef CONFIG_ATFILE
295
/*
296
 * Host system seems to have atfile syscall stubs available.  We
297
 * now enable them one by one as specified by target syscall_nr.h.
298
 */
299

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

    
371
      /*
372
       * Get the 'mode' parameter and translate it to
373
       * host bits.
374
       */
375
      va_start(ap, flags);
376
      mode = va_arg(ap, mode_t);
377
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
378
      va_end(ap);
379

    
380
      return (openat(dirfd, pathname, flags, mode));
381
  }
382
  return (openat(dirfd, pathname, flags));
383
}
384
#endif
385
#ifdef TARGET_NR_readlinkat
386
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
387
{
388
  return (readlinkat(dirfd, pathname, buf, bufsiz));
389
}
390
#endif
391
#ifdef TARGET_NR_renameat
392
static int sys_renameat(int olddirfd, const char *oldpath,
393
    int newdirfd, const char *newpath)
394
{
395
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
396
}
397
#endif
398
#ifdef TARGET_NR_symlinkat
399
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
400
{
401
  return (symlinkat(oldpath, newdirfd, newpath));
402
}
403
#endif
404
#ifdef TARGET_NR_unlinkat
405
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
406
{
407
  return (unlinkat(dirfd, pathname, flags));
408
}
409
#endif
410
#else /* !CONFIG_ATFILE */
411

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

    
469
#endif /* CONFIG_ATFILE */
470

    
471
#ifdef CONFIG_UTIMENSAT
472
static int sys_utimensat(int dirfd, const char *pathname,
473
    const struct timespec times[2], int flags)
474
{
475
    if (pathname == NULL)
476
        return futimens(dirfd, times);
477
    else
478
        return utimensat(dirfd, pathname, times, flags);
479
}
480
#else
481
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
482
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
483
          const struct timespec *,tsp,int,flags)
484
#endif
485
#endif /* CONFIG_UTIMENSAT  */
486

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

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

    
515

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

    
522
#define ERRNO_TABLE_SIZE 1200
523

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

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

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

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

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

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

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

    
673
static abi_ulong target_brk;
674
static abi_ulong target_original_brk;
675

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

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

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

    
693
    brk_page = HOST_PAGE_ALIGN(target_brk);
694

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

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

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

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

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

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

    
740
    unlock_user(target_fds, target_fds_addr, 0);
741

    
742
    return 0;
743
}
744

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

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

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

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

    
772
    return 0;
773
}
774

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

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

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

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

    
817
    return 0;
818
}
819

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

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

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

    
831
    unlock_user_struct(target_tv, target_tv_addr, 0);
832

    
833
    return 0;
834
}
835

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

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

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

    
847
    unlock_user_struct(target_tv, target_tv_addr, 1);
848

    
849
    return 0;
850
}
851

    
852
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_ip_mreq(struct ip_mreqn *mreqn,
948
                                              abi_ulong target_addr,
949
                                              socklen_t len)
950
{
951
    struct target_ip_mreqn *target_smreqn;
952

    
953
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
954
    if (!target_smreqn)
955
        return -TARGET_EFAULT;
956
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
957
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
958
    if (len == sizeof(struct target_ip_mreqn))
959
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
960
    unlock_user(target_smreqn, target_addr, 0);
961

    
962
    return 0;
963
}
964

    
965
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
966
                                               abi_ulong target_addr,
967
                                               socklen_t len)
968
{
969
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
970
    sa_family_t sa_family;
971
    struct target_sockaddr *target_saddr;
972

    
973
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
974
    if (!target_saddr)
975
        return -TARGET_EFAULT;
976

    
977
    sa_family = tswap16(target_saddr->sa_family);
978

    
979
    /* Oops. The caller might send a incomplete sun_path; sun_path
980
     * must be terminated by \0 (see the manual page), but
981
     * unfortunately it is quite common to specify sockaddr_un
982
     * length as "strlen(x->sun_path)" while it should be
983
     * "strlen(...) + 1". We'll fix that here if needed.
984
     * Linux kernel has a similar feature.
985
     */
986

    
987
    if (sa_family == AF_UNIX) {
988
        if (len < unix_maxlen && len > 0) {
989
            char *cp = (char*)target_saddr;
990

    
991
            if ( cp[len-1] && !cp[len] )
992
                len++;
993
        }
994
        if (len > unix_maxlen)
995
            len = unix_maxlen;
996
    }
997

    
998
    memcpy(addr, target_saddr, len);
999
    addr->sa_family = sa_family;
1000
    unlock_user(target_saddr, target_addr, 0);
1001

    
1002
    return 0;
1003
}
1004

    
1005
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1006
                                               struct sockaddr *addr,
1007
                                               socklen_t len)
1008
{
1009
    struct target_sockaddr *target_saddr;
1010

    
1011
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1012
    if (!target_saddr)
1013
        return -TARGET_EFAULT;
1014
    memcpy(target_saddr, addr, len);
1015
    target_saddr->sa_family = tswap16(addr->sa_family);
1016
    unlock_user(target_saddr, target_addr, len);
1017

    
1018
    return 0;
1019
}
1020

    
1021
/* ??? Should this also swap msgh->name?  */
1022
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1023
                                           struct target_msghdr *target_msgh)
1024
{
1025
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1026
    abi_long msg_controllen;
1027
    abi_ulong target_cmsg_addr;
1028
    struct target_cmsghdr *target_cmsg;
1029
    socklen_t space = 0;
1030
    
1031
    msg_controllen = tswapl(target_msgh->msg_controllen);
1032
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1033
        goto the_end;
1034
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1035
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1036
    if (!target_cmsg)
1037
        return -TARGET_EFAULT;
1038

    
1039
    while (cmsg && target_cmsg) {
1040
        void *data = CMSG_DATA(cmsg);
1041
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1042

    
1043
        int len = tswapl(target_cmsg->cmsg_len)
1044
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1045

    
1046
        space += CMSG_SPACE(len);
1047
        if (space > msgh->msg_controllen) {
1048
            space -= CMSG_SPACE(len);
1049
            gemu_log("Host cmsg overflow\n");
1050
            break;
1051
        }
1052

    
1053
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1054
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1055
        cmsg->cmsg_len = CMSG_LEN(len);
1056

    
1057
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1058
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1059
            memcpy(data, target_data, len);
1060
        } else {
1061
            int *fd = (int *)data;
1062
            int *target_fd = (int *)target_data;
1063
            int i, numfds = len / sizeof(int);
1064

    
1065
            for (i = 0; i < numfds; i++)
1066
                fd[i] = tswap32(target_fd[i]);
1067
        }
1068

    
1069
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1070
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1071
    }
1072
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1073
 the_end:
1074
    msgh->msg_controllen = space;
1075
    return 0;
1076
}
1077

    
1078
/* ??? Should this also swap msgh->name?  */
1079
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1080
                                           struct msghdr *msgh)
1081
{
1082
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1083
    abi_long msg_controllen;
1084
    abi_ulong target_cmsg_addr;
1085
    struct target_cmsghdr *target_cmsg;
1086
    socklen_t space = 0;
1087

    
1088
    msg_controllen = tswapl(target_msgh->msg_controllen);
1089
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1090
        goto the_end;
1091
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1092
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1093
    if (!target_cmsg)
1094
        return -TARGET_EFAULT;
1095

    
1096
    while (cmsg && target_cmsg) {
1097
        void *data = CMSG_DATA(cmsg);
1098
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1099

    
1100
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1101

    
1102
        space += TARGET_CMSG_SPACE(len);
1103
        if (space > msg_controllen) {
1104
            space -= TARGET_CMSG_SPACE(len);
1105
            gemu_log("Target cmsg overflow\n");
1106
            break;
1107
        }
1108

    
1109
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1110
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1111
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1112

    
1113
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1114
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1115
            memcpy(target_data, data, len);
1116
        } else {
1117
            int *fd = (int *)data;
1118
            int *target_fd = (int *)target_data;
1119
            int i, numfds = len / sizeof(int);
1120

    
1121
            for (i = 0; i < numfds; i++)
1122
                target_fd[i] = tswap32(fd[i]);
1123
        }
1124

    
1125
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1126
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1127
    }
1128
    unlock_user(target_cmsg, target_cmsg_addr, space);
1129
 the_end:
1130
    target_msgh->msg_controllen = tswapl(space);
1131
    return 0;
1132
}
1133

    
1134
/* do_setsockopt() Must return target values and target errnos. */
1135
static abi_long do_setsockopt(int sockfd, int level, int optname,
1136
                              abi_ulong optval_addr, socklen_t optlen)
1137
{
1138
    abi_long ret;
1139
    int val;
1140
    struct ip_mreqn *ip_mreq;
1141
    struct ip_mreq_source *ip_mreq_source;
1142

    
1143
    switch(level) {
1144
    case SOL_TCP:
1145
        /* TCP options all take an 'int' value.  */
1146
        if (optlen < sizeof(uint32_t))
1147
            return -TARGET_EINVAL;
1148

    
1149
        if (get_user_u32(val, optval_addr))
1150
            return -TARGET_EFAULT;
1151
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1152
        break;
1153
    case SOL_IP:
1154
        switch(optname) {
1155
        case IP_TOS:
1156
        case IP_TTL:
1157
        case IP_HDRINCL:
1158
        case IP_ROUTER_ALERT:
1159
        case IP_RECVOPTS:
1160
        case IP_RETOPTS:
1161
        case IP_PKTINFO:
1162
        case IP_MTU_DISCOVER:
1163
        case IP_RECVERR:
1164
        case IP_RECVTOS:
1165
#ifdef IP_FREEBIND
1166
        case IP_FREEBIND:
1167
#endif
1168
        case IP_MULTICAST_TTL:
1169
        case IP_MULTICAST_LOOP:
1170
            val = 0;
1171
            if (optlen >= sizeof(uint32_t)) {
1172
                if (get_user_u32(val, optval_addr))
1173
                    return -TARGET_EFAULT;
1174
            } else if (optlen >= 1) {
1175
                if (get_user_u8(val, optval_addr))
1176
                    return -TARGET_EFAULT;
1177
            }
1178
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1179
            break;
1180
        case IP_ADD_MEMBERSHIP:
1181
        case IP_DROP_MEMBERSHIP:
1182
            if (optlen < sizeof (struct target_ip_mreq) ||
1183
                optlen > sizeof (struct target_ip_mreqn))
1184
                return -TARGET_EINVAL;
1185

    
1186
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1187
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1188
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1189
            break;
1190

    
1191
        case IP_BLOCK_SOURCE:
1192
        case IP_UNBLOCK_SOURCE:
1193
        case IP_ADD_SOURCE_MEMBERSHIP:
1194
        case IP_DROP_SOURCE_MEMBERSHIP:
1195
            if (optlen != sizeof (struct target_ip_mreq_source))
1196
                return -TARGET_EINVAL;
1197

    
1198
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1199
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1200
            unlock_user (ip_mreq_source, optval_addr, 0);
1201
            break;
1202

    
1203
        default:
1204
            goto unimplemented;
1205
        }
1206
        break;
1207
    case TARGET_SOL_SOCKET:
1208
        switch (optname) {
1209
            /* Options with 'int' argument.  */
1210
        case TARGET_SO_DEBUG:
1211
                optname = SO_DEBUG;
1212
                break;
1213
        case TARGET_SO_REUSEADDR:
1214
                optname = SO_REUSEADDR;
1215
                break;
1216
        case TARGET_SO_TYPE:
1217
                optname = SO_TYPE;
1218
                break;
1219
        case TARGET_SO_ERROR:
1220
                optname = SO_ERROR;
1221
                break;
1222
        case TARGET_SO_DONTROUTE:
1223
                optname = SO_DONTROUTE;
1224
                break;
1225
        case TARGET_SO_BROADCAST:
1226
                optname = SO_BROADCAST;
1227
                break;
1228
        case TARGET_SO_SNDBUF:
1229
                optname = SO_SNDBUF;
1230
                break;
1231
        case TARGET_SO_RCVBUF:
1232
                optname = SO_RCVBUF;
1233
                break;
1234
        case TARGET_SO_KEEPALIVE:
1235
                optname = SO_KEEPALIVE;
1236
                break;
1237
        case TARGET_SO_OOBINLINE:
1238
                optname = SO_OOBINLINE;
1239
                break;
1240
        case TARGET_SO_NO_CHECK:
1241
                optname = SO_NO_CHECK;
1242
                break;
1243
        case TARGET_SO_PRIORITY:
1244
                optname = SO_PRIORITY;
1245
                break;
1246
#ifdef SO_BSDCOMPAT
1247
        case TARGET_SO_BSDCOMPAT:
1248
                optname = SO_BSDCOMPAT;
1249
                break;
1250
#endif
1251
        case TARGET_SO_PASSCRED:
1252
                optname = SO_PASSCRED;
1253
                break;
1254
        case TARGET_SO_TIMESTAMP:
1255
                optname = SO_TIMESTAMP;
1256
                break;
1257
        case TARGET_SO_RCVLOWAT:
1258
                optname = SO_RCVLOWAT;
1259
                break;
1260
        case TARGET_SO_RCVTIMEO:
1261
                optname = SO_RCVTIMEO;
1262
                break;
1263
        case TARGET_SO_SNDTIMEO:
1264
                optname = SO_SNDTIMEO;
1265
                break;
1266
            break;
1267
        default:
1268
            goto unimplemented;
1269
        }
1270
        if (optlen < sizeof(uint32_t))
1271
            return -TARGET_EINVAL;
1272

    
1273
        if (get_user_u32(val, optval_addr))
1274
            return -TARGET_EFAULT;
1275
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1276
        break;
1277
    default:
1278
    unimplemented:
1279
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1280
        ret = -TARGET_ENOPROTOOPT;
1281
    }
1282
    return ret;
1283
}
1284

    
1285
/* do_getsockopt() Must return target values and target errnos. */
1286
static abi_long do_getsockopt(int sockfd, int level, int optname,
1287
                              abi_ulong optval_addr, abi_ulong optlen)
1288
{
1289
    abi_long ret;
1290
    int len, val;
1291
    socklen_t lv;
1292

    
1293
    switch(level) {
1294
    case TARGET_SOL_SOCKET:
1295
            level = SOL_SOCKET;
1296
        switch (optname) {
1297
        case TARGET_SO_LINGER:
1298
        case TARGET_SO_RCVTIMEO:
1299
        case TARGET_SO_SNDTIMEO:
1300
        case TARGET_SO_PEERCRED:
1301
        case TARGET_SO_PEERNAME:
1302
            /* These don't just return a single integer */
1303
            goto unimplemented;
1304
        default:
1305
            goto int_case;
1306
        }
1307
        break;
1308
    case SOL_TCP:
1309
        /* TCP options all take an 'int' value.  */
1310
    int_case:
1311
        if (get_user_u32(len, optlen))
1312
            return -TARGET_EFAULT;
1313
        if (len < 0)
1314
            return -TARGET_EINVAL;
1315
        lv = sizeof(int);
1316
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1317
        if (ret < 0)
1318
            return ret;
1319
        val = tswap32(val);
1320
        if (len > lv)
1321
            len = lv;
1322
        if (len == 4) {
1323
            if (put_user_u32(val, optval_addr))
1324
                return -TARGET_EFAULT;
1325
        } else {
1326
            if (put_user_u8(val, optval_addr))
1327
                return -TARGET_EFAULT;
1328
        }
1329
        if (put_user_u32(len, optlen))
1330
            return -TARGET_EFAULT;
1331
        break;
1332
    case SOL_IP:
1333
        switch(optname) {
1334
        case IP_TOS:
1335
        case IP_TTL:
1336
        case IP_HDRINCL:
1337
        case IP_ROUTER_ALERT:
1338
        case IP_RECVOPTS:
1339
        case IP_RETOPTS:
1340
        case IP_PKTINFO:
1341
        case IP_MTU_DISCOVER:
1342
        case IP_RECVERR:
1343
        case IP_RECVTOS:
1344
#ifdef IP_FREEBIND
1345
        case IP_FREEBIND:
1346
#endif
1347
        case IP_MULTICAST_TTL:
1348
        case IP_MULTICAST_LOOP:
1349
            if (get_user_u32(len, optlen))
1350
                return -TARGET_EFAULT;
1351
            if (len < 0)
1352
                return -TARGET_EINVAL;
1353
            lv = sizeof(int);
1354
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1355
            if (ret < 0)
1356
                return ret;
1357
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1358
                len = 1;
1359
                if (put_user_u32(len, optlen)
1360
                    || put_user_u8(val, optval_addr))
1361
                    return -TARGET_EFAULT;
1362
            } else {
1363
                if (len > sizeof(int))
1364
                    len = sizeof(int);
1365
                if (put_user_u32(len, optlen)
1366
                    || put_user_u32(val, optval_addr))
1367
                    return -TARGET_EFAULT;
1368
            }
1369
            break;
1370
        default:
1371
            ret = -TARGET_ENOPROTOOPT;
1372
            break;
1373
        }
1374
        break;
1375
    default:
1376
    unimplemented:
1377
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1378
                 level, optname);
1379
        ret = -TARGET_EOPNOTSUPP;
1380
        break;
1381
    }
1382
    return ret;
1383
}
1384

    
1385
/* FIXME
1386
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1387
 * other lock functions have a return code of 0 for failure.
1388
 */
1389
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1390
                           int count, int copy)
1391
{
1392
    struct target_iovec *target_vec;
1393
    abi_ulong base;
1394
    int i;
1395

    
1396
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1397
    if (!target_vec)
1398
        return -TARGET_EFAULT;
1399
    for(i = 0;i < count; i++) {
1400
        base = tswapl(target_vec[i].iov_base);
1401
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1402
        if (vec[i].iov_len != 0) {
1403
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1404
            /* Don't check lock_user return value. We must call writev even
1405
               if a element has invalid base address. */
1406
        } else {
1407
            /* zero length pointer is ignored */
1408
            vec[i].iov_base = NULL;
1409
        }
1410
    }
1411
    unlock_user (target_vec, target_addr, 0);
1412
    return 0;
1413
}
1414

    
1415
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1416
                             int count, int copy)
1417
{
1418
    struct target_iovec *target_vec;
1419
    abi_ulong base;
1420
    int i;
1421

    
1422
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1423
    if (!target_vec)
1424
        return -TARGET_EFAULT;
1425
    for(i = 0;i < count; i++) {
1426
        if (target_vec[i].iov_base) {
1427
            base = tswapl(target_vec[i].iov_base);
1428
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1429
        }
1430
    }
1431
    unlock_user (target_vec, target_addr, 0);
1432

    
1433
    return 0;
1434
}
1435

    
1436
/* do_socket() Must return target values and target errnos. */
1437
static abi_long do_socket(int domain, int type, int protocol)
1438
{
1439
#if defined(TARGET_MIPS)
1440
    switch(type) {
1441
    case TARGET_SOCK_DGRAM:
1442
        type = SOCK_DGRAM;
1443
        break;
1444
    case TARGET_SOCK_STREAM:
1445
        type = SOCK_STREAM;
1446
        break;
1447
    case TARGET_SOCK_RAW:
1448
        type = SOCK_RAW;
1449
        break;
1450
    case TARGET_SOCK_RDM:
1451
        type = SOCK_RDM;
1452
        break;
1453
    case TARGET_SOCK_SEQPACKET:
1454
        type = SOCK_SEQPACKET;
1455
        break;
1456
    case TARGET_SOCK_PACKET:
1457
        type = SOCK_PACKET;
1458
        break;
1459
    }
1460
#endif
1461
    if (domain == PF_NETLINK)
1462
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1463
    return get_errno(socket(domain, type, protocol));
1464
}
1465

    
1466
/* do_bind() Must return target values and target errnos. */
1467
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1468
                        socklen_t addrlen)
1469
{
1470
    void *addr;
1471

    
1472
    if (addrlen < 0)
1473
        return -TARGET_EINVAL;
1474

    
1475
    addr = alloca(addrlen+1);
1476

    
1477
    target_to_host_sockaddr(addr, target_addr, addrlen);
1478
    return get_errno(bind(sockfd, addr, addrlen));
1479
}
1480

    
1481
/* do_connect() Must return target values and target errnos. */
1482
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1483
                           socklen_t addrlen)
1484
{
1485
    void *addr;
1486

    
1487
    if (addrlen < 0)
1488
        return -TARGET_EINVAL;
1489

    
1490
    addr = alloca(addrlen);
1491

    
1492
    target_to_host_sockaddr(addr, target_addr, addrlen);
1493
    return get_errno(connect(sockfd, addr, addrlen));
1494
}
1495

    
1496
/* do_sendrecvmsg() Must return target values and target errnos. */
1497
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1498
                               int flags, int send)
1499
{
1500
    abi_long ret, len;
1501
    struct target_msghdr *msgp;
1502
    struct msghdr msg;
1503
    int count;
1504
    struct iovec *vec;
1505
    abi_ulong target_vec;
1506

    
1507
    /* FIXME */
1508
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1509
                          msgp,
1510
                          target_msg,
1511
                          send ? 1 : 0))
1512
        return -TARGET_EFAULT;
1513
    if (msgp->msg_name) {
1514
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1515
        msg.msg_name = alloca(msg.msg_namelen);
1516
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1517
                                msg.msg_namelen);
1518
    } else {
1519
        msg.msg_name = NULL;
1520
        msg.msg_namelen = 0;
1521
    }
1522
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1523
    msg.msg_control = alloca(msg.msg_controllen);
1524
    msg.msg_flags = tswap32(msgp->msg_flags);
1525

    
1526
    count = tswapl(msgp->msg_iovlen);
1527
    vec = alloca(count * sizeof(struct iovec));
1528
    target_vec = tswapl(msgp->msg_iov);
1529
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1530
    msg.msg_iovlen = count;
1531
    msg.msg_iov = vec;
1532

    
1533
    if (send) {
1534
        ret = target_to_host_cmsg(&msg, msgp);
1535
        if (ret == 0)
1536
            ret = get_errno(sendmsg(fd, &msg, flags));
1537
    } else {
1538
        ret = get_errno(recvmsg(fd, &msg, flags));
1539
        if (!is_error(ret)) {
1540
            len = ret;
1541
            ret = host_to_target_cmsg(msgp, &msg);
1542
            if (!is_error(ret))
1543
                ret = len;
1544
        }
1545
    }
1546
    unlock_iovec(vec, target_vec, count, !send);
1547
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1548
    return ret;
1549
}
1550

    
1551
/* do_accept() Must return target values and target errnos. */
1552
static abi_long do_accept(int fd, abi_ulong target_addr,
1553
                          abi_ulong target_addrlen_addr)
1554
{
1555
    socklen_t addrlen;
1556
    void *addr;
1557
    abi_long ret;
1558

    
1559
    if (get_user_u32(addrlen, target_addrlen_addr))
1560
        return -TARGET_EFAULT;
1561

    
1562
    if (addrlen < 0)
1563
        return -TARGET_EINVAL;
1564

    
1565
    addr = alloca(addrlen);
1566

    
1567
    ret = get_errno(accept(fd, addr, &addrlen));
1568
    if (!is_error(ret)) {
1569
        host_to_target_sockaddr(target_addr, addr, addrlen);
1570
        if (put_user_u32(addrlen, target_addrlen_addr))
1571
            ret = -TARGET_EFAULT;
1572
    }
1573
    return ret;
1574
}
1575

    
1576
/* do_getpeername() Must return target values and target errnos. */
1577
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1578
                               abi_ulong target_addrlen_addr)
1579
{
1580
    socklen_t addrlen;
1581
    void *addr;
1582
    abi_long ret;
1583

    
1584
    if (get_user_u32(addrlen, target_addrlen_addr))
1585
        return -TARGET_EFAULT;
1586

    
1587
    if (addrlen < 0)
1588
        return -TARGET_EINVAL;
1589

    
1590
    addr = alloca(addrlen);
1591

    
1592
    ret = get_errno(getpeername(fd, addr, &addrlen));
1593
    if (!is_error(ret)) {
1594
        host_to_target_sockaddr(target_addr, addr, addrlen);
1595
        if (put_user_u32(addrlen, target_addrlen_addr))
1596
            ret = -TARGET_EFAULT;
1597
    }
1598
    return ret;
1599
}
1600

    
1601
/* do_getsockname() Must return target values and target errnos. */
1602
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1603
                               abi_ulong target_addrlen_addr)
1604
{
1605
    socklen_t addrlen;
1606
    void *addr;
1607
    abi_long ret;
1608

    
1609
    if (target_addr == 0)
1610
       return get_errno(accept(fd, NULL, NULL));
1611

    
1612
    if (get_user_u32(addrlen, target_addrlen_addr))
1613
        return -TARGET_EFAULT;
1614

    
1615
    if (addrlen < 0)
1616
        return -TARGET_EINVAL;
1617

    
1618
    addr = alloca(addrlen);
1619

    
1620
    ret = get_errno(getsockname(fd, addr, &addrlen));
1621
    if (!is_error(ret)) {
1622
        host_to_target_sockaddr(target_addr, addr, addrlen);
1623
        if (put_user_u32(addrlen, target_addrlen_addr))
1624
            ret = -TARGET_EFAULT;
1625
    }
1626
    return ret;
1627
}
1628

    
1629
/* do_socketpair() Must return target values and target errnos. */
1630
static abi_long do_socketpair(int domain, int type, int protocol,
1631
                              abi_ulong target_tab_addr)
1632
{
1633
    int tab[2];
1634
    abi_long ret;
1635

    
1636
    ret = get_errno(socketpair(domain, type, protocol, tab));
1637
    if (!is_error(ret)) {
1638
        if (put_user_s32(tab[0], target_tab_addr)
1639
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1640
            ret = -TARGET_EFAULT;
1641
    }
1642
    return ret;
1643
}
1644

    
1645
/* do_sendto() Must return target values and target errnos. */
1646
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1647
                          abi_ulong target_addr, socklen_t addrlen)
1648
{
1649
    void *addr;
1650
    void *host_msg;
1651
    abi_long ret;
1652

    
1653
    if (addrlen < 0)
1654
        return -TARGET_EINVAL;
1655

    
1656
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1657
    if (!host_msg)
1658
        return -TARGET_EFAULT;
1659
    if (target_addr) {
1660
        addr = alloca(addrlen);
1661
        target_to_host_sockaddr(addr, target_addr, addrlen);
1662
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1663
    } else {
1664
        ret = get_errno(send(fd, host_msg, len, flags));
1665
    }
1666
    unlock_user(host_msg, msg, 0);
1667
    return ret;
1668
}
1669

    
1670
/* do_recvfrom() Must return target values and target errnos. */
1671
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1672
                            abi_ulong target_addr,
1673
                            abi_ulong target_addrlen)
1674
{
1675
    socklen_t addrlen;
1676
    void *addr;
1677
    void *host_msg;
1678
    abi_long ret;
1679

    
1680
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1681
    if (!host_msg)
1682
        return -TARGET_EFAULT;
1683
    if (target_addr) {
1684
        if (get_user_u32(addrlen, target_addrlen)) {
1685
            ret = -TARGET_EFAULT;
1686
            goto fail;
1687
        }
1688
        if (addrlen < 0) {
1689
            ret = -TARGET_EINVAL;
1690
            goto fail;
1691
        }
1692
        addr = alloca(addrlen);
1693
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1694
    } else {
1695
        addr = NULL; /* To keep compiler quiet.  */
1696
        ret = get_errno(recv(fd, host_msg, len, flags));
1697
    }
1698
    if (!is_error(ret)) {
1699
        if (target_addr) {
1700
            host_to_target_sockaddr(target_addr, addr, addrlen);
1701
            if (put_user_u32(addrlen, target_addrlen)) {
1702
                ret = -TARGET_EFAULT;
1703
                goto fail;
1704
            }
1705
        }
1706
        unlock_user(host_msg, msg, len);
1707
    } else {
1708
fail:
1709
        unlock_user(host_msg, msg, 0);
1710
    }
1711
    return ret;
1712
}
1713

    
1714
#ifdef TARGET_NR_socketcall
1715
/* do_socketcall() Must return target values and target errnos. */
1716
static abi_long do_socketcall(int num, abi_ulong vptr)
1717
{
1718
    abi_long ret;
1719
    const int n = sizeof(abi_ulong);
1720

    
1721
    switch(num) {
1722
    case SOCKOP_socket:
1723
        {
1724
            int domain, type, protocol;
1725

    
1726
            if (get_user_s32(domain, vptr)
1727
                || get_user_s32(type, vptr + n)
1728
                || get_user_s32(protocol, vptr + 2 * n))
1729
                return -TARGET_EFAULT;
1730

    
1731
            ret = do_socket(domain, type, protocol);
1732
        }
1733
        break;
1734
    case SOCKOP_bind:
1735
        {
1736
            int sockfd;
1737
            abi_ulong target_addr;
1738
            socklen_t addrlen;
1739

    
1740
            if (get_user_s32(sockfd, vptr)
1741
                || get_user_ual(target_addr, vptr + n)
1742
                || get_user_u32(addrlen, vptr + 2 * n))
1743
                return -TARGET_EFAULT;
1744

    
1745
            ret = do_bind(sockfd, target_addr, addrlen);
1746
        }
1747
        break;
1748
    case SOCKOP_connect:
1749
        {
1750
            int sockfd;
1751
            abi_ulong target_addr;
1752
            socklen_t addrlen;
1753

    
1754
            if (get_user_s32(sockfd, vptr)
1755
                || get_user_ual(target_addr, vptr + n)
1756
                || get_user_u32(addrlen, vptr + 2 * n))
1757
                return -TARGET_EFAULT;
1758

    
1759
            ret = do_connect(sockfd, target_addr, addrlen);
1760
        }
1761
        break;
1762
    case SOCKOP_listen:
1763
        {
1764
            int sockfd, backlog;
1765

    
1766
            if (get_user_s32(sockfd, vptr)
1767
                || get_user_s32(backlog, vptr + n))
1768
                return -TARGET_EFAULT;
1769

    
1770
            ret = get_errno(listen(sockfd, backlog));
1771
        }
1772
        break;
1773
    case SOCKOP_accept:
1774
        {
1775
            int sockfd;
1776
            abi_ulong target_addr, target_addrlen;
1777

    
1778
            if (get_user_s32(sockfd, vptr)
1779
                || get_user_ual(target_addr, vptr + n)
1780
                || get_user_u32(target_addrlen, vptr + 2 * n))
1781
                return -TARGET_EFAULT;
1782

    
1783
            ret = do_accept(sockfd, target_addr, target_addrlen);
1784
        }
1785
        break;
1786
    case SOCKOP_getsockname:
1787
        {
1788
            int sockfd;
1789
            abi_ulong target_addr, target_addrlen;
1790

    
1791
            if (get_user_s32(sockfd, vptr)
1792
                || get_user_ual(target_addr, vptr + n)
1793
                || get_user_u32(target_addrlen, vptr + 2 * n))
1794
                return -TARGET_EFAULT;
1795

    
1796
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1797
        }
1798
        break;
1799
    case SOCKOP_getpeername:
1800
        {
1801
            int sockfd;
1802
            abi_ulong target_addr, target_addrlen;
1803

    
1804
            if (get_user_s32(sockfd, vptr)
1805
                || get_user_ual(target_addr, vptr + n)
1806
                || get_user_u32(target_addrlen, vptr + 2 * n))
1807
                return -TARGET_EFAULT;
1808

    
1809
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1810
        }
1811
        break;
1812
    case SOCKOP_socketpair:
1813
        {
1814
            int domain, type, protocol;
1815
            abi_ulong tab;
1816

    
1817
            if (get_user_s32(domain, vptr)
1818
                || get_user_s32(type, vptr + n)
1819
                || get_user_s32(protocol, vptr + 2 * n)
1820
                || get_user_ual(tab, vptr + 3 * n))
1821
                return -TARGET_EFAULT;
1822

    
1823
            ret = do_socketpair(domain, type, protocol, tab);
1824
        }
1825
        break;
1826
    case SOCKOP_send:
1827
        {
1828
            int sockfd;
1829
            abi_ulong msg;
1830
            size_t len;
1831
            int flags;
1832

    
1833
            if (get_user_s32(sockfd, vptr)
1834
                || get_user_ual(msg, vptr + n)
1835
                || get_user_ual(len, vptr + 2 * n)
1836
                || get_user_s32(flags, vptr + 3 * n))
1837
                return -TARGET_EFAULT;
1838

    
1839
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1840
        }
1841
        break;
1842
    case SOCKOP_recv:
1843
        {
1844
            int sockfd;
1845
            abi_ulong msg;
1846
            size_t len;
1847
            int flags;
1848

    
1849
            if (get_user_s32(sockfd, vptr)
1850
                || get_user_ual(msg, vptr + n)
1851
                || get_user_ual(len, vptr + 2 * n)
1852
                || get_user_s32(flags, vptr + 3 * n))
1853
                return -TARGET_EFAULT;
1854

    
1855
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1856
        }
1857
        break;
1858
    case SOCKOP_sendto:
1859
        {
1860
            int sockfd;
1861
            abi_ulong msg;
1862
            size_t len;
1863
            int flags;
1864
            abi_ulong addr;
1865
            socklen_t addrlen;
1866

    
1867
            if (get_user_s32(sockfd, vptr)
1868
                || get_user_ual(msg, vptr + n)
1869
                || get_user_ual(len, vptr + 2 * n)
1870
                || get_user_s32(flags, vptr + 3 * n)
1871
                || get_user_ual(addr, vptr + 4 * n)
1872
                || get_user_u32(addrlen, vptr + 5 * n))
1873
                return -TARGET_EFAULT;
1874

    
1875
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1876
        }
1877
        break;
1878
    case SOCKOP_recvfrom:
1879
        {
1880
            int sockfd;
1881
            abi_ulong msg;
1882
            size_t len;
1883
            int flags;
1884
            abi_ulong addr;
1885
            socklen_t addrlen;
1886

    
1887
            if (get_user_s32(sockfd, vptr)
1888
                || get_user_ual(msg, vptr + n)
1889
                || get_user_ual(len, vptr + 2 * n)
1890
                || get_user_s32(flags, vptr + 3 * n)
1891
                || get_user_ual(addr, vptr + 4 * n)
1892
                || get_user_u32(addrlen, vptr + 5 * n))
1893
                return -TARGET_EFAULT;
1894

    
1895
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1896
        }
1897
        break;
1898
    case SOCKOP_shutdown:
1899
        {
1900
            int sockfd, how;
1901

    
1902
            if (get_user_s32(sockfd, vptr)
1903
                || get_user_s32(how, vptr + n))
1904
                return -TARGET_EFAULT;
1905

    
1906
            ret = get_errno(shutdown(sockfd, how));
1907
        }
1908
        break;
1909
    case SOCKOP_sendmsg:
1910
    case SOCKOP_recvmsg:
1911
        {
1912
            int fd;
1913
            abi_ulong target_msg;
1914
            int flags;
1915

    
1916
            if (get_user_s32(fd, vptr)
1917
                || get_user_ual(target_msg, vptr + n)
1918
                || get_user_s32(flags, vptr + 2 * n))
1919
                return -TARGET_EFAULT;
1920

    
1921
            ret = do_sendrecvmsg(fd, target_msg, flags,
1922
                                 (num == SOCKOP_sendmsg));
1923
        }
1924
        break;
1925
    case SOCKOP_setsockopt:
1926
        {
1927
            int sockfd;
1928
            int level;
1929
            int optname;
1930
            abi_ulong optval;
1931
            socklen_t optlen;
1932

    
1933
            if (get_user_s32(sockfd, vptr)
1934
                || get_user_s32(level, vptr + n)
1935
                || get_user_s32(optname, vptr + 2 * n)
1936
                || get_user_ual(optval, vptr + 3 * n)
1937
                || get_user_u32(optlen, vptr + 4 * n))
1938
                return -TARGET_EFAULT;
1939

    
1940
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1941
        }
1942
        break;
1943
    case SOCKOP_getsockopt:
1944
        {
1945
            int sockfd;
1946
            int level;
1947
            int optname;
1948
            abi_ulong optval;
1949
            socklen_t optlen;
1950

    
1951
            if (get_user_s32(sockfd, vptr)
1952
                || get_user_s32(level, vptr + n)
1953
                || get_user_s32(optname, vptr + 2 * n)
1954
                || get_user_ual(optval, vptr + 3 * n)
1955
                || get_user_u32(optlen, vptr + 4 * n))
1956
                return -TARGET_EFAULT;
1957

    
1958
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1959
        }
1960
        break;
1961
    default:
1962
        gemu_log("Unsupported socketcall: %d\n", num);
1963
        ret = -TARGET_ENOSYS;
1964
        break;
1965
    }
1966
    return ret;
1967
}
1968
#endif
1969

    
1970
#define N_SHM_REGIONS        32
1971

    
1972
static struct shm_region {
1973
    abi_ulong        start;
1974
    abi_ulong        size;
1975
} shm_regions[N_SHM_REGIONS];
1976

    
1977
struct target_ipc_perm
1978
{
1979
    abi_long __key;
1980
    abi_ulong uid;
1981
    abi_ulong gid;
1982
    abi_ulong cuid;
1983
    abi_ulong cgid;
1984
    unsigned short int mode;
1985
    unsigned short int __pad1;
1986
    unsigned short int __seq;
1987
    unsigned short int __pad2;
1988
    abi_ulong __unused1;
1989
    abi_ulong __unused2;
1990
};
1991

    
1992
struct target_semid_ds
1993
{
1994
  struct target_ipc_perm sem_perm;
1995
  abi_ulong sem_otime;
1996
  abi_ulong __unused1;
1997
  abi_ulong sem_ctime;
1998
  abi_ulong __unused2;
1999
  abi_ulong sem_nsems;
2000
  abi_ulong __unused3;
2001
  abi_ulong __unused4;
2002
};
2003

    
2004
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2005
                                               abi_ulong target_addr)
2006
{
2007
    struct target_ipc_perm *target_ip;
2008
    struct target_semid_ds *target_sd;
2009

    
2010
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2011
        return -TARGET_EFAULT;
2012
    target_ip=&(target_sd->sem_perm);
2013
    host_ip->__key = tswapl(target_ip->__key);
2014
    host_ip->uid = tswapl(target_ip->uid);
2015
    host_ip->gid = tswapl(target_ip->gid);
2016
    host_ip->cuid = tswapl(target_ip->cuid);
2017
    host_ip->cgid = tswapl(target_ip->cgid);
2018
    host_ip->mode = tswapl(target_ip->mode);
2019
    unlock_user_struct(target_sd, target_addr, 0);
2020
    return 0;
2021
}
2022

    
2023
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2024
                                               struct ipc_perm *host_ip)
2025
{
2026
    struct target_ipc_perm *target_ip;
2027
    struct target_semid_ds *target_sd;
2028

    
2029
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2030
        return -TARGET_EFAULT;
2031
    target_ip = &(target_sd->sem_perm);
2032
    target_ip->__key = tswapl(host_ip->__key);
2033
    target_ip->uid = tswapl(host_ip->uid);
2034
    target_ip->gid = tswapl(host_ip->gid);
2035
    target_ip->cuid = tswapl(host_ip->cuid);
2036
    target_ip->cgid = tswapl(host_ip->cgid);
2037
    target_ip->mode = tswapl(host_ip->mode);
2038
    unlock_user_struct(target_sd, target_addr, 1);
2039
    return 0;
2040
}
2041

    
2042
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2043
                                               abi_ulong target_addr)
2044
{
2045
    struct target_semid_ds *target_sd;
2046

    
2047
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2048
        return -TARGET_EFAULT;
2049
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2050
        return -TARGET_EFAULT;
2051
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2052
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2053
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2054
    unlock_user_struct(target_sd, target_addr, 0);
2055
    return 0;
2056
}
2057

    
2058
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2059
                                               struct semid_ds *host_sd)
2060
{
2061
    struct target_semid_ds *target_sd;
2062

    
2063
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2064
        return -TARGET_EFAULT;
2065
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2066
        return -TARGET_EFAULT;;
2067
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2068
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2069
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2070
    unlock_user_struct(target_sd, target_addr, 1);
2071
    return 0;
2072
}
2073

    
2074
struct target_seminfo {
2075
    int semmap;
2076
    int semmni;
2077
    int semmns;
2078
    int semmnu;
2079
    int semmsl;
2080
    int semopm;
2081
    int semume;
2082
    int semusz;
2083
    int semvmx;
2084
    int semaem;
2085
};
2086

    
2087
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2088
                                              struct seminfo *host_seminfo)
2089
{
2090
    struct target_seminfo *target_seminfo;
2091
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2092
        return -TARGET_EFAULT;
2093
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2094
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2095
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2096
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2097
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2098
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2099
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2100
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2101
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2102
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2103
    unlock_user_struct(target_seminfo, target_addr, 1);
2104
    return 0;
2105
}
2106

    
2107
union semun {
2108
        int val;
2109
        struct semid_ds *buf;
2110
        unsigned short *array;
2111
        struct seminfo *__buf;
2112
};
2113

    
2114
union target_semun {
2115
        int val;
2116
        abi_ulong buf;
2117
        abi_ulong array;
2118
        abi_ulong __buf;
2119
};
2120

    
2121
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2122
                                               abi_ulong target_addr)
2123
{
2124
    int nsems;
2125
    unsigned short *array;
2126
    union semun semun;
2127
    struct semid_ds semid_ds;
2128
    int i, ret;
2129

    
2130
    semun.buf = &semid_ds;
2131

    
2132
    ret = semctl(semid, 0, IPC_STAT, semun);
2133
    if (ret == -1)
2134
        return get_errno(ret);
2135

    
2136
    nsems = semid_ds.sem_nsems;
2137

    
2138
    *host_array = malloc(nsems*sizeof(unsigned short));
2139
    array = lock_user(VERIFY_READ, target_addr,
2140
                      nsems*sizeof(unsigned short), 1);
2141
    if (!array)
2142
        return -TARGET_EFAULT;
2143

    
2144
    for(i=0; i<nsems; i++) {
2145
        __get_user((*host_array)[i], &array[i]);
2146
    }
2147
    unlock_user(array, target_addr, 0);
2148

    
2149
    return 0;
2150
}
2151

    
2152
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2153
                                               unsigned short **host_array)
2154
{
2155
    int nsems;
2156
    unsigned short *array;
2157
    union semun semun;
2158
    struct semid_ds semid_ds;
2159
    int i, ret;
2160

    
2161
    semun.buf = &semid_ds;
2162

    
2163
    ret = semctl(semid, 0, IPC_STAT, semun);
2164
    if (ret == -1)
2165
        return get_errno(ret);
2166

    
2167
    nsems = semid_ds.sem_nsems;
2168

    
2169
    array = lock_user(VERIFY_WRITE, target_addr,
2170
                      nsems*sizeof(unsigned short), 0);
2171
    if (!array)
2172
        return -TARGET_EFAULT;
2173

    
2174
    for(i=0; i<nsems; i++) {
2175
        __put_user((*host_array)[i], &array[i]);
2176
    }
2177
    free(*host_array);
2178
    unlock_user(array, target_addr, 1);
2179

    
2180
    return 0;
2181
}
2182

    
2183
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2184
                                 union target_semun target_su)
2185
{
2186
    union semun arg;
2187
    struct semid_ds dsarg;
2188
    unsigned short *array;
2189
    struct seminfo seminfo;
2190
    abi_long ret = -TARGET_EINVAL;
2191
    abi_long err;
2192
    cmd &= 0xff;
2193

    
2194
    switch( cmd ) {
2195
        case GETVAL:
2196
        case SETVAL:
2197
            arg.val = tswapl(target_su.val);
2198
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2199
            target_su.val = tswapl(arg.val);
2200
            break;
2201
        case GETALL:
2202
        case SETALL:
2203
            err = target_to_host_semarray(semid, &array, target_su.array);
2204
            if (err)
2205
                return err;
2206
            arg.array = array;
2207
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2208
            err = host_to_target_semarray(semid, target_su.array, &array);
2209
            if (err)
2210
                return err;
2211
            break;
2212
        case IPC_STAT:
2213
        case IPC_SET:
2214
        case SEM_STAT:
2215
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2216
            if (err)
2217
                return err;
2218
            arg.buf = &dsarg;
2219
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2220
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2221
            if (err)
2222
                return err;
2223
            break;
2224
        case IPC_INFO:
2225
        case SEM_INFO:
2226
            arg.__buf = &seminfo;
2227
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2228
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2229
            if (err)
2230
                return err;
2231
            break;
2232
        case IPC_RMID:
2233
        case GETPID:
2234
        case GETNCNT:
2235
        case GETZCNT:
2236
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2237
            break;
2238
    }
2239

    
2240
    return ret;
2241
}
2242

    
2243
struct target_sembuf {
2244
    unsigned short sem_num;
2245
    short sem_op;
2246
    short sem_flg;
2247
};
2248

    
2249
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2250
                                             abi_ulong target_addr,
2251
                                             unsigned nsops)
2252
{
2253
    struct target_sembuf *target_sembuf;
2254
    int i;
2255

    
2256
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2257
                              nsops*sizeof(struct target_sembuf), 1);
2258
    if (!target_sembuf)
2259
        return -TARGET_EFAULT;
2260

    
2261
    for(i=0; i<nsops; i++) {
2262
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2263
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2264
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2265
    }
2266

    
2267
    unlock_user(target_sembuf, target_addr, 0);
2268

    
2269
    return 0;
2270
}
2271

    
2272
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2273
{
2274
    struct sembuf sops[nsops];
2275

    
2276
    if (target_to_host_sembuf(sops, ptr, nsops))
2277
        return -TARGET_EFAULT;
2278

    
2279
    return semop(semid, sops, nsops);
2280
}
2281

    
2282
struct target_msqid_ds
2283
{
2284
    struct target_ipc_perm msg_perm;
2285
    abi_ulong msg_stime;
2286
#if TARGET_ABI_BITS == 32
2287
    abi_ulong __unused1;
2288
#endif
2289
    abi_ulong msg_rtime;
2290
#if TARGET_ABI_BITS == 32
2291
    abi_ulong __unused2;
2292
#endif
2293
    abi_ulong msg_ctime;
2294
#if TARGET_ABI_BITS == 32
2295
    abi_ulong __unused3;
2296
#endif
2297
    abi_ulong __msg_cbytes;
2298
    abi_ulong msg_qnum;
2299
    abi_ulong msg_qbytes;
2300
    abi_ulong msg_lspid;
2301
    abi_ulong msg_lrpid;
2302
    abi_ulong __unused4;
2303
    abi_ulong __unused5;
2304
};
2305

    
2306
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2307
                                               abi_ulong target_addr)
2308
{
2309
    struct target_msqid_ds *target_md;
2310

    
2311
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2312
        return -TARGET_EFAULT;
2313
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2314
        return -TARGET_EFAULT;
2315
    host_md->msg_stime = tswapl(target_md->msg_stime);
2316
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2317
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2318
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2319
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2320
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2321
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2322
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2323
    unlock_user_struct(target_md, target_addr, 0);
2324
    return 0;
2325
}
2326

    
2327
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2328
                                               struct msqid_ds *host_md)
2329
{
2330
    struct target_msqid_ds *target_md;
2331

    
2332
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2333
        return -TARGET_EFAULT;
2334
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2335
        return -TARGET_EFAULT;
2336
    target_md->msg_stime = tswapl(host_md->msg_stime);
2337
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2338
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2339
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2340
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2341
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2342
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2343
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2344
    unlock_user_struct(target_md, target_addr, 1);
2345
    return 0;
2346
}
2347

    
2348
struct target_msginfo {
2349
    int msgpool;
2350
    int msgmap;
2351
    int msgmax;
2352
    int msgmnb;
2353
    int msgmni;
2354
    int msgssz;
2355
    int msgtql;
2356
    unsigned short int msgseg;
2357
};
2358

    
2359
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2360
                                              struct msginfo *host_msginfo)
2361
{
2362
    struct target_msginfo *target_msginfo;
2363
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2364
        return -TARGET_EFAULT;
2365
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2366
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2367
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2368
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2369
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2370
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2371
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2372
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2373
    unlock_user_struct(target_msginfo, target_addr, 1);
2374
    return 0;
2375
}
2376

    
2377
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2378
{
2379
    struct msqid_ds dsarg;
2380
    struct msginfo msginfo;
2381
    abi_long ret = -TARGET_EINVAL;
2382

    
2383
    cmd &= 0xff;
2384

    
2385
    switch (cmd) {
2386
    case IPC_STAT:
2387
    case IPC_SET:
2388
    case MSG_STAT:
2389
        if (target_to_host_msqid_ds(&dsarg,ptr))
2390
            return -TARGET_EFAULT;
2391
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2392
        if (host_to_target_msqid_ds(ptr,&dsarg))
2393
            return -TARGET_EFAULT;
2394
        break;
2395
    case IPC_RMID:
2396
        ret = get_errno(msgctl(msgid, cmd, NULL));
2397
        break;
2398
    case IPC_INFO:
2399
    case MSG_INFO:
2400
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2401
        if (host_to_target_msginfo(ptr, &msginfo))
2402
            return -TARGET_EFAULT;
2403
        break;
2404
    }
2405

    
2406
    return ret;
2407
}
2408

    
2409
struct target_msgbuf {
2410
    abi_long mtype;
2411
    char        mtext[1];
2412
};
2413

    
2414
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2415
                                 unsigned int msgsz, int msgflg)
2416
{
2417
    struct target_msgbuf *target_mb;
2418
    struct msgbuf *host_mb;
2419
    abi_long ret = 0;
2420

    
2421
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2422
        return -TARGET_EFAULT;
2423
    host_mb = malloc(msgsz+sizeof(long));
2424
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2425
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2426
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2427
    free(host_mb);
2428
    unlock_user_struct(target_mb, msgp, 0);
2429

    
2430
    return ret;
2431
}
2432

    
2433
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2434
                                 unsigned int msgsz, abi_long msgtyp,
2435
                                 int msgflg)
2436
{
2437
    struct target_msgbuf *target_mb;
2438
    char *target_mtext;
2439
    struct msgbuf *host_mb;
2440
    abi_long ret = 0;
2441

    
2442
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2443
        return -TARGET_EFAULT;
2444

    
2445
    host_mb = malloc(msgsz+sizeof(long));
2446
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2447

    
2448
    if (ret > 0) {
2449
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2450
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2451
        if (!target_mtext) {
2452
            ret = -TARGET_EFAULT;
2453
            goto end;
2454
        }
2455
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2456
        unlock_user(target_mtext, target_mtext_addr, ret);
2457
    }
2458

    
2459
    target_mb->mtype = tswapl(host_mb->mtype);
2460
    free(host_mb);
2461

    
2462
end:
2463
    if (target_mb)
2464
        unlock_user_struct(target_mb, msgp, 1);
2465
    return ret;
2466
}
2467

    
2468
struct target_shmid_ds
2469
{
2470
    struct target_ipc_perm shm_perm;
2471
    abi_ulong shm_segsz;
2472
    abi_ulong shm_atime;
2473
#if TARGET_ABI_BITS == 32
2474
    abi_ulong __unused1;
2475
#endif
2476
    abi_ulong shm_dtime;
2477
#if TARGET_ABI_BITS == 32
2478
    abi_ulong __unused2;
2479
#endif
2480
    abi_ulong shm_ctime;
2481
#if TARGET_ABI_BITS == 32
2482
    abi_ulong __unused3;
2483
#endif
2484
    int shm_cpid;
2485
    int shm_lpid;
2486
    abi_ulong shm_nattch;
2487
    unsigned long int __unused4;
2488
    unsigned long int __unused5;
2489
};
2490

    
2491
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2492
                                               abi_ulong target_addr)
2493
{
2494
    struct target_shmid_ds *target_sd;
2495

    
2496
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2497
        return -TARGET_EFAULT;
2498
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2499
        return -TARGET_EFAULT;
2500
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2501
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2502
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2503
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2504
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2505
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2506
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2507
    unlock_user_struct(target_sd, target_addr, 0);
2508
    return 0;
2509
}
2510

    
2511
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2512
                                               struct shmid_ds *host_sd)
2513
{
2514
    struct target_shmid_ds *target_sd;
2515

    
2516
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2517
        return -TARGET_EFAULT;
2518
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2519
        return -TARGET_EFAULT;
2520
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2521
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2522
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2523
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2524
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2525
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2526
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2527
    unlock_user_struct(target_sd, target_addr, 1);
2528
    return 0;
2529
}
2530

    
2531
struct  target_shminfo {
2532
    abi_ulong shmmax;
2533
    abi_ulong shmmin;
2534
    abi_ulong shmmni;
2535
    abi_ulong shmseg;
2536
    abi_ulong shmall;
2537
};
2538

    
2539
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2540
                                              struct shminfo *host_shminfo)
2541
{
2542
    struct target_shminfo *target_shminfo;
2543
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2544
        return -TARGET_EFAULT;
2545
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2546
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2547
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2548
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2549
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2550
    unlock_user_struct(target_shminfo, target_addr, 1);
2551
    return 0;
2552
}
2553

    
2554
struct target_shm_info {
2555
    int used_ids;
2556
    abi_ulong shm_tot;
2557
    abi_ulong shm_rss;
2558
    abi_ulong shm_swp;
2559
    abi_ulong swap_attempts;
2560
    abi_ulong swap_successes;
2561
};
2562

    
2563
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2564
                                               struct shm_info *host_shm_info)
2565
{
2566
    struct target_shm_info *target_shm_info;
2567
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2568
        return -TARGET_EFAULT;
2569
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2570
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2571
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2572
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2573
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2574
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2575
    unlock_user_struct(target_shm_info, target_addr, 1);
2576
    return 0;
2577
}
2578

    
2579
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2580
{
2581
    struct shmid_ds dsarg;
2582
    struct shminfo shminfo;
2583
    struct shm_info shm_info;
2584
    abi_long ret = -TARGET_EINVAL;
2585

    
2586
    cmd &= 0xff;
2587

    
2588
    switch(cmd) {
2589
    case IPC_STAT:
2590
    case IPC_SET:
2591
    case SHM_STAT:
2592
        if (target_to_host_shmid_ds(&dsarg, buf))
2593
            return -TARGET_EFAULT;
2594
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2595
        if (host_to_target_shmid_ds(buf, &dsarg))
2596
            return -TARGET_EFAULT;
2597
        break;
2598
    case IPC_INFO:
2599
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2600
        if (host_to_target_shminfo(buf, &shminfo))
2601
            return -TARGET_EFAULT;
2602
        break;
2603
    case SHM_INFO:
2604
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2605
        if (host_to_target_shm_info(buf, &shm_info))
2606
            return -TARGET_EFAULT;
2607
        break;
2608
    case IPC_RMID:
2609
    case SHM_LOCK:
2610
    case SHM_UNLOCK:
2611
        ret = get_errno(shmctl(shmid, cmd, NULL));
2612
        break;
2613
    }
2614

    
2615
    return ret;
2616
}
2617

    
2618
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2619
{
2620
    abi_long raddr;
2621
    void *host_raddr;
2622
    struct shmid_ds shm_info;
2623
    int i,ret;
2624

    
2625
    /* find out the length of the shared memory segment */
2626
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2627
    if (is_error(ret)) {
2628
        /* can't get length, bail out */
2629
        return ret;
2630
    }
2631

    
2632
    mmap_lock();
2633

    
2634
    if (shmaddr)
2635
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2636
    else {
2637
        abi_ulong mmap_start;
2638

    
2639
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2640

    
2641
        if (mmap_start == -1) {
2642
            errno = ENOMEM;
2643
            host_raddr = (void *)-1;
2644
        } else
2645
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2646
    }
2647

    
2648
    if (host_raddr == (void *)-1) {
2649
        mmap_unlock();
2650
        return get_errno((long)host_raddr);
2651
    }
2652
    raddr=h2g((unsigned long)host_raddr);
2653

    
2654
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2655
                   PAGE_VALID | PAGE_READ |
2656
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2657

    
2658
    for (i = 0; i < N_SHM_REGIONS; i++) {
2659
        if (shm_regions[i].start == 0) {
2660
            shm_regions[i].start = raddr;
2661
            shm_regions[i].size = shm_info.shm_segsz;
2662
            break;
2663
        }
2664
    }
2665

    
2666
    mmap_unlock();
2667
    return raddr;
2668

    
2669
}
2670

    
2671
static inline abi_long do_shmdt(abi_ulong shmaddr)
2672
{
2673
    int i;
2674

    
2675
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2676
        if (shm_regions[i].start == shmaddr) {
2677
            shm_regions[i].start = 0;
2678
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2679
            break;
2680
        }
2681
    }
2682

    
2683
    return get_errno(shmdt(g2h(shmaddr)));
2684
}
2685

    
2686
#ifdef TARGET_NR_ipc
2687
/* ??? This only works with linear mappings.  */
2688
/* do_ipc() must return target values and target errnos. */
2689
static abi_long do_ipc(unsigned int call, int first,
2690
                       int second, int third,
2691
                       abi_long ptr, abi_long fifth)
2692
{
2693
    int version;
2694
    abi_long ret = 0;
2695

    
2696
    version = call >> 16;
2697
    call &= 0xffff;
2698

    
2699
    switch (call) {
2700
    case IPCOP_semop:
2701
        ret = do_semop(first, ptr, second);
2702
        break;
2703

    
2704
    case IPCOP_semget:
2705
        ret = get_errno(semget(first, second, third));
2706
        break;
2707

    
2708
    case IPCOP_semctl:
2709
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2710
        break;
2711

    
2712
    case IPCOP_msgget:
2713
        ret = get_errno(msgget(first, second));
2714
        break;
2715

    
2716
    case IPCOP_msgsnd:
2717
        ret = do_msgsnd(first, ptr, second, third);
2718
        break;
2719

    
2720
    case IPCOP_msgctl:
2721
        ret = do_msgctl(first, second, ptr);
2722
        break;
2723

    
2724
    case IPCOP_msgrcv:
2725
        switch (version) {
2726
        case 0:
2727
            {
2728
                struct target_ipc_kludge {
2729
                    abi_long msgp;
2730
                    abi_long msgtyp;
2731
                } *tmp;
2732

    
2733
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2734
                    ret = -TARGET_EFAULT;
2735
                    break;
2736
                }
2737

    
2738
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2739

    
2740
                unlock_user_struct(tmp, ptr, 0);
2741
                break;
2742
            }
2743
        default:
2744
            ret = do_msgrcv(first, ptr, second, fifth, third);
2745
        }
2746
        break;
2747

    
2748
    case IPCOP_shmat:
2749
        switch (version) {
2750
        default:
2751
        {
2752
            abi_ulong raddr;
2753
            raddr = do_shmat(first, ptr, second);
2754
            if (is_error(raddr))
2755
                return get_errno(raddr);
2756
            if (put_user_ual(raddr, third))
2757
                return -TARGET_EFAULT;
2758
            break;
2759
        }
2760
        case 1:
2761
            ret = -TARGET_EINVAL;
2762
            break;
2763
        }
2764
        break;
2765
    case IPCOP_shmdt:
2766
        ret = do_shmdt(ptr);
2767
        break;
2768

    
2769
    case IPCOP_shmget:
2770
        /* IPC_* flag values are the same on all linux platforms */
2771
        ret = get_errno(shmget(first, second, third));
2772
        break;
2773

    
2774
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2775
    case IPCOP_shmctl:
2776
        ret = do_shmctl(first, second, third);
2777
        break;
2778
    default:
2779
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2780
        ret = -TARGET_ENOSYS;
2781
        break;
2782
    }
2783
    return ret;
2784
}
2785
#endif
2786

    
2787
/* kernel structure types definitions */
2788
#define IFNAMSIZ        16
2789

    
2790
#define STRUCT(name, ...) STRUCT_ ## name,
2791
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2792
enum {
2793
#include "syscall_types.h"
2794
};
2795
#undef STRUCT
2796
#undef STRUCT_SPECIAL
2797

    
2798
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2799
#define STRUCT_SPECIAL(name)
2800
#include "syscall_types.h"
2801
#undef STRUCT
2802
#undef STRUCT_SPECIAL
2803

    
2804
typedef struct IOCTLEntry {
2805
    unsigned int target_cmd;
2806
    unsigned int host_cmd;
2807
    const char *name;
2808
    int access;
2809
    const argtype arg_type[5];
2810
} IOCTLEntry;
2811

    
2812
#define IOC_R 0x0001
2813
#define IOC_W 0x0002
2814
#define IOC_RW (IOC_R | IOC_W)
2815

    
2816
#define MAX_STRUCT_SIZE 4096
2817

    
2818
static IOCTLEntry ioctl_entries[] = {
2819
#define IOCTL(cmd, access, ...) \
2820
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2821
#include "ioctls.h"
2822
    { 0, 0, },
2823
};
2824

    
2825
/* ??? Implement proper locking for ioctls.  */
2826
/* do_ioctl() Must return target values and target errnos. */
2827
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2828
{
2829
    const IOCTLEntry *ie;
2830
    const argtype *arg_type;
2831
    abi_long ret;
2832
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2833
    int target_size;
2834
    void *argptr;
2835

    
2836
    ie = ioctl_entries;
2837
    for(;;) {
2838
        if (ie->target_cmd == 0) {
2839
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2840
            return -TARGET_ENOSYS;
2841
        }
2842
        if (ie->target_cmd == cmd)
2843
            break;
2844
        ie++;
2845
    }
2846
    arg_type = ie->arg_type;
2847
#if defined(DEBUG)
2848
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2849
#endif
2850
    switch(arg_type[0]) {
2851
    case TYPE_NULL:
2852
        /* no argument */
2853
        ret = get_errno(ioctl(fd, ie->host_cmd));
2854
        break;
2855
    case TYPE_PTRVOID:
2856
    case TYPE_INT:
2857
        /* int argment */
2858
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2859
        break;
2860
    case TYPE_PTR:
2861
        arg_type++;
2862
        target_size = thunk_type_size(arg_type, 0);
2863
        switch(ie->access) {
2864
        case IOC_R:
2865
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2866
            if (!is_error(ret)) {
2867
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2868
                if (!argptr)
2869
                    return -TARGET_EFAULT;
2870
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2871
                unlock_user(argptr, arg, target_size);
2872
            }
2873
            break;
2874
        case IOC_W:
2875
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2876
            if (!argptr)
2877
                return -TARGET_EFAULT;
2878
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2879
            unlock_user(argptr, arg, 0);
2880
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2881
            break;
2882
        default:
2883
        case IOC_RW:
2884
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2885
            if (!argptr)
2886
                return -TARGET_EFAULT;
2887
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2888
            unlock_user(argptr, arg, 0);
2889
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2890
            if (!is_error(ret)) {
2891
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2892
                if (!argptr)
2893
                    return -TARGET_EFAULT;
2894
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2895
                unlock_user(argptr, arg, target_size);
2896
            }
2897
            break;
2898
        }
2899
        break;
2900
    default:
2901
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2902
                 (long)cmd, arg_type[0]);
2903
        ret = -TARGET_ENOSYS;
2904
        break;
2905
    }
2906
    return ret;
2907
}
2908

    
2909
static const bitmask_transtbl iflag_tbl[] = {
2910
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2911
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2912
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2913
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2914
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2915
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2916
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2917
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2918
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2919
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2920
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2921
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2922
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2923
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2924
        { 0, 0, 0, 0 }
2925
};
2926

    
2927
static const bitmask_transtbl oflag_tbl[] = {
2928
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2929
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2930
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2931
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2932
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2933
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2934
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2935
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2936
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2937
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2938
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2939
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2940
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2941
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2942
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2943
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2944
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2945
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2946
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2947
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2948
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2949
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2950
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2951
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2952
        { 0, 0, 0, 0 }
2953
};
2954

    
2955
static const bitmask_transtbl cflag_tbl[] = {
2956
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2957
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2958
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2959
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2960
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2961
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2962
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2963
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2964
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2965
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2966
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2967
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2968
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2969
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2970
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2971
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2972
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2973
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2974
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2975
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2976
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2977
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2978
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2979
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2980
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2981
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2982
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2983
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2984
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2985
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2986
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2987
        { 0, 0, 0, 0 }
2988
};
2989

    
2990
static const bitmask_transtbl lflag_tbl[] = {
2991
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2992
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2993
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2994
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2995
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2996
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2997
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2998
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2999
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3000
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3001
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3002
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3003
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3004
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3005
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3006
        { 0, 0, 0, 0 }
3007
};
3008

    
3009
static void target_to_host_termios (void *dst, const void *src)
3010
{
3011
    struct host_termios *host = dst;
3012
    const struct target_termios *target = src;
3013

    
3014
    host->c_iflag =
3015
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3016
    host->c_oflag =
3017
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3018
    host->c_cflag =
3019
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3020
    host->c_lflag =
3021
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3022
    host->c_line = target->c_line;
3023

    
3024
    memset(host->c_cc, 0, sizeof(host->c_cc));
3025
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3026
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3027
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3028
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3029
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3030
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3031
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3032
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3033
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3034
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3035
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3036
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3037
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3038
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3039
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3040
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3041
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3042
}
3043

    
3044
static void host_to_target_termios (void *dst, const void *src)
3045
{
3046
    struct target_termios *target = dst;
3047
    const struct host_termios *host = src;
3048

    
3049
    target->c_iflag =
3050
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3051
    target->c_oflag =
3052
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3053
    target->c_cflag =
3054
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3055
    target->c_lflag =
3056
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3057
    target->c_line = host->c_line;
3058

    
3059
    memset(target->c_cc, 0, sizeof(target->c_cc));
3060
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3061
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3062
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3063
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3064
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3065
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3066
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3067
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3068
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3069
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3070
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3071
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3072
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3073
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3074
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3075
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3076
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3077
}
3078

    
3079
static const StructEntry struct_termios_def = {
3080
    .convert = { host_to_target_termios, target_to_host_termios },
3081
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3082
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3083
};
3084

    
3085
static bitmask_transtbl mmap_flags_tbl[] = {
3086
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3087
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3088
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3089
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3090
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3091
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3092
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3093
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3094
        { 0, 0, 0, 0 }
3095
};
3096

    
3097
#if defined(TARGET_I386)
3098

    
3099
/* NOTE: there is really one LDT for all the threads */
3100
static uint8_t *ldt_table;
3101

    
3102
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3103
{
3104
    int size;
3105
    void *p;
3106

    
3107
    if (!ldt_table)
3108
        return 0;
3109
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3110
    if (size > bytecount)
3111
        size = bytecount;
3112
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3113
    if (!p)
3114
        return -TARGET_EFAULT;
3115
    /* ??? Should this by byteswapped?  */
3116
    memcpy(p, ldt_table, size);
3117
    unlock_user(p, ptr, size);
3118
    return size;
3119
}
3120

    
3121
/* XXX: add locking support */
3122
static abi_long write_ldt(CPUX86State *env,
3123
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3124
{
3125
    struct target_modify_ldt_ldt_s ldt_info;
3126
    struct target_modify_ldt_ldt_s *target_ldt_info;
3127
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3128
    int seg_not_present, useable, lm;
3129
    uint32_t *lp, entry_1, entry_2;
3130

    
3131
    if (bytecount != sizeof(ldt_info))
3132
        return -TARGET_EINVAL;
3133
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3134
        return -TARGET_EFAULT;
3135
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3136
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3137
    ldt_info.limit = tswap32(target_ldt_info->limit);
3138
    ldt_info.flags = tswap32(target_ldt_info->flags);
3139
    unlock_user_struct(target_ldt_info, ptr, 0);
3140

    
3141
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3142
        return -TARGET_EINVAL;
3143
    seg_32bit = ldt_info.flags & 1;
3144
    contents = (ldt_info.flags >> 1) & 3;
3145
    read_exec_only = (ldt_info.flags >> 3) & 1;
3146
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3147
    seg_not_present = (ldt_info.flags >> 5) & 1;
3148
    useable = (ldt_info.flags >> 6) & 1;
3149
#ifdef TARGET_ABI32
3150
    lm = 0;
3151
#else
3152
    lm = (ldt_info.flags >> 7) & 1;
3153
#endif
3154
    if (contents == 3) {
3155
        if (oldmode)
3156
            return -TARGET_EINVAL;
3157
        if (seg_not_present == 0)
3158
            return -TARGET_EINVAL;
3159
    }
3160
    /* allocate the LDT */
3161
    if (!ldt_table) {
3162
        env->ldt.base = target_mmap(0,
3163
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3164
                                    PROT_READ|PROT_WRITE,
3165
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3166
        if (env->ldt.base == -1)
3167
            return -TARGET_ENOMEM;
3168
        memset(g2h(env->ldt.base), 0,
3169
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3170
        env->ldt.limit = 0xffff;
3171
        ldt_table = g2h(env->ldt.base);
3172
    }
3173

    
3174
    /* NOTE: same code as Linux kernel */
3175
    /* Allow LDTs to be cleared by the user. */
3176
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3177
        if (oldmode ||
3178
            (contents == 0                &&
3179
             read_exec_only == 1        &&
3180
             seg_32bit == 0                &&
3181
             limit_in_pages == 0        &&
3182
             seg_not_present == 1        &&
3183
             useable == 0 )) {
3184
            entry_1 = 0;
3185
            entry_2 = 0;
3186
            goto install;
3187
        }
3188
    }
3189

    
3190
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3191
        (ldt_info.limit & 0x0ffff);
3192
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3193
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3194
        (ldt_info.limit & 0xf0000) |
3195
        ((read_exec_only ^ 1) << 9) |
3196
        (contents << 10) |
3197
        ((seg_not_present ^ 1) << 15) |
3198
        (seg_32bit << 22) |
3199
        (limit_in_pages << 23) |
3200
        (lm << 21) |
3201
        0x7000;
3202
    if (!oldmode)
3203
        entry_2 |= (useable << 20);
3204

    
3205
    /* Install the new entry ...  */
3206
install:
3207
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3208
    lp[0] = tswap32(entry_1);
3209
    lp[1] = tswap32(entry_2);
3210
    return 0;
3211
}
3212

    
3213
/* specific and weird i386 syscalls */
3214
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3215
                              unsigned long bytecount)
3216
{
3217
    abi_long ret;
3218

    
3219
    switch (func) {
3220
    case 0:
3221
        ret = read_ldt(ptr, bytecount);
3222
        break;
3223
    case 1:
3224
        ret = write_ldt(env, ptr, bytecount, 1);
3225
        break;
3226
    case 0x11:
3227
        ret = write_ldt(env, ptr, bytecount, 0);
3228
        break;
3229
    default:
3230
        ret = -TARGET_ENOSYS;
3231
        break;
3232
    }
3233
    return ret;
3234
}
3235

    
3236
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3237
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3238
{
3239
    uint64_t *gdt_table = g2h(env->gdt.base);
3240
    struct target_modify_ldt_ldt_s ldt_info;
3241
    struct target_modify_ldt_ldt_s *target_ldt_info;
3242
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3243
    int seg_not_present, useable, lm;
3244
    uint32_t *lp, entry_1, entry_2;
3245
    int i;
3246

    
3247
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3248
    if (!target_ldt_info)
3249
        return -TARGET_EFAULT;
3250
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3251
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3252
    ldt_info.limit = tswap32(target_ldt_info->limit);
3253
    ldt_info.flags = tswap32(target_ldt_info->flags);
3254
    if (ldt_info.entry_number == -1) {
3255
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3256
            if (gdt_table[i] == 0) {
3257
                ldt_info.entry_number = i;
3258
                target_ldt_info->entry_number = tswap32(i);
3259
                break;
3260
            }
3261
        }
3262
    }
3263
    unlock_user_struct(target_ldt_info, ptr, 1);
3264

    
3265
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3266
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3267
           return -TARGET_EINVAL;
3268
    seg_32bit = ldt_info.flags & 1;
3269
    contents = (ldt_info.flags >> 1) & 3;
3270
    read_exec_only = (ldt_info.flags >> 3) & 1;
3271
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3272
    seg_not_present = (ldt_info.flags >> 5) & 1;
3273
    useable = (ldt_info.flags >> 6) & 1;
3274
#ifdef TARGET_ABI32
3275
    lm = 0;
3276
#else
3277
    lm = (ldt_info.flags >> 7) & 1;
3278
#endif
3279

    
3280
    if (contents == 3) {
3281
        if (seg_not_present == 0)
3282
            return -TARGET_EINVAL;
3283
    }
3284

    
3285
    /* NOTE: same code as Linux kernel */
3286
    /* Allow LDTs to be cleared by the user. */
3287
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3288
        if ((contents == 0             &&
3289
             read_exec_only == 1       &&
3290
             seg_32bit == 0            &&
3291
             limit_in_pages == 0       &&
3292
             seg_not_present == 1      &&
3293
             useable == 0 )) {
3294
            entry_1 = 0;
3295
            entry_2 = 0;
3296
            goto install;
3297
        }
3298
    }
3299

    
3300
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3301
        (ldt_info.limit & 0x0ffff);
3302
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3303
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3304
        (ldt_info.limit & 0xf0000) |
3305
        ((read_exec_only ^ 1) << 9) |
3306
        (contents << 10) |
3307
        ((seg_not_present ^ 1) << 15) |
3308
        (seg_32bit << 22) |
3309
        (limit_in_pages << 23) |
3310
        (useable << 20) |
3311
        (lm << 21) |
3312
        0x7000;
3313

    
3314
    /* Install the new entry ...  */
3315
install:
3316
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3317
    lp[0] = tswap32(entry_1);
3318
    lp[1] = tswap32(entry_2);
3319
    return 0;
3320
}
3321

    
3322
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3323
{
3324
    struct target_modify_ldt_ldt_s *target_ldt_info;
3325
    uint64_t *gdt_table = g2h(env->gdt.base);
3326
    uint32_t base_addr, limit, flags;
3327
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3328
    int seg_not_present, useable, lm;
3329
    uint32_t *lp, entry_1, entry_2;
3330

    
3331
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3332
    if (!target_ldt_info)
3333
        return -TARGET_EFAULT;
3334
    idx = tswap32(target_ldt_info->entry_number);
3335
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3336
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3337
        unlock_user_struct(target_ldt_info, ptr, 1);
3338
        return -TARGET_EINVAL;
3339
    }
3340
    lp = (uint32_t *)(gdt_table + idx);
3341
    entry_1 = tswap32(lp[0]);
3342
    entry_2 = tswap32(lp[1]);
3343
    
3344
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3345
    contents = (entry_2 >> 10) & 3;
3346
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3347
    seg_32bit = (entry_2 >> 22) & 1;
3348
    limit_in_pages = (entry_2 >> 23) & 1;
3349
    useable = (entry_2 >> 20) & 1;
3350
#ifdef TARGET_ABI32
3351
    lm = 0;
3352
#else
3353
    lm = (entry_2 >> 21) & 1;
3354
#endif
3355
    flags = (seg_32bit << 0) | (contents << 1) |
3356
        (read_exec_only << 3) | (limit_in_pages << 4) |
3357
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3358
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3359
    base_addr = (entry_1 >> 16) | 
3360
        (entry_2 & 0xff000000) | 
3361
        ((entry_2 & 0xff) << 16);
3362
    target_ldt_info->base_addr = tswapl(base_addr);
3363
    target_ldt_info->limit = tswap32(limit);
3364
    target_ldt_info->flags = tswap32(flags);
3365
    unlock_user_struct(target_ldt_info, ptr, 1);
3366
    return 0;
3367
}
3368
#endif /* TARGET_I386 && TARGET_ABI32 */
3369

    
3370
#ifndef TARGET_ABI32
3371
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3372
{
3373
    abi_long ret;
3374
    abi_ulong val;
3375
    int idx;
3376
    
3377
    switch(code) {
3378
    case TARGET_ARCH_SET_GS:
3379
    case TARGET_ARCH_SET_FS:
3380
        if (code == TARGET_ARCH_SET_GS)
3381
            idx = R_GS;
3382
        else
3383
            idx = R_FS;
3384
        cpu_x86_load_seg(env, idx, 0);
3385
        env->segs[idx].base = addr;
3386
        break;
3387
    case TARGET_ARCH_GET_GS:
3388
    case TARGET_ARCH_GET_FS:
3389
        if (code == TARGET_ARCH_GET_GS)
3390
            idx = R_GS;
3391
        else
3392
            idx = R_FS;
3393
        val = env->segs[idx].base;
3394
        if (put_user(val, addr, abi_ulong))
3395
            return -TARGET_EFAULT;
3396
        break;
3397
    default:
3398
        ret = -TARGET_EINVAL;
3399
        break;
3400
    }
3401
    return 0;
3402
}
3403
#endif
3404

    
3405
#endif /* defined(TARGET_I386) */
3406

    
3407
#if defined(USE_NPTL)
3408

    
3409
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3410

    
3411
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3412
typedef struct {
3413
    CPUState *env;
3414
    pthread_mutex_t mutex;
3415
    pthread_cond_t cond;
3416
    pthread_t thread;
3417
    uint32_t tid;
3418
    abi_ulong child_tidptr;
3419
    abi_ulong parent_tidptr;
3420
    sigset_t sigmask;
3421
} new_thread_info;
3422

    
3423
static void *clone_func(void *arg)
3424
{
3425
    new_thread_info *info = arg;
3426
    CPUState *env;
3427
    TaskState *ts;
3428

    
3429
    env = info->env;
3430
    thread_env = env;
3431
    ts = (TaskState *)thread_env->opaque;
3432
    info->tid = gettid();
3433
    env->host_tid = info->tid;
3434
    task_settid(ts);
3435
    if (info->child_tidptr)
3436
        put_user_u32(info->tid, info->child_tidptr);
3437
    if (info->parent_tidptr)
3438
        put_user_u32(info->tid, info->parent_tidptr);
3439
    /* Enable signals.  */
3440
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3441
    /* Signal to the parent that we're ready.  */
3442
    pthread_mutex_lock(&info->mutex);
3443
    pthread_cond_broadcast(&info->cond);
3444
    pthread_mutex_unlock(&info->mutex);
3445
    /* Wait until the parent has finshed initializing the tls state.  */
3446
    pthread_mutex_lock(&clone_lock);
3447
    pthread_mutex_unlock(&clone_lock);
3448
    cpu_loop(env);
3449
    /* never exits */
3450
    return NULL;
3451
}
3452
#else
3453
/* this stack is the equivalent of the kernel stack associated with a
3454
   thread/process */
3455
#define NEW_STACK_SIZE 8192
3456

    
3457
static int clone_func(void *arg)
3458
{
3459
    CPUState *env = arg;
3460
    cpu_loop(env);
3461
    /* never exits */
3462
    return 0;
3463
}
3464
#endif
3465

    
3466
/* do_fork() Must return host values and target errnos (unlike most
3467
   do_*() functions). */
3468
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3469
                   abi_ulong parent_tidptr, target_ulong newtls,
3470
                   abi_ulong child_tidptr)
3471
{
3472
    int ret;
3473
    TaskState *ts;
3474
    uint8_t *new_stack;
3475
    CPUState *new_env;
3476
#if defined(USE_NPTL)
3477
    unsigned int nptl_flags;
3478
    sigset_t sigmask;
3479
#endif
3480

    
3481
    /* Emulate vfork() with fork() */
3482
    if (flags & CLONE_VFORK)
3483
        flags &= ~(CLONE_VFORK | CLONE_VM);
3484

    
3485
    if (flags & CLONE_VM) {
3486
        TaskState *parent_ts = (TaskState *)env->opaque;
3487
#if defined(USE_NPTL)
3488
        new_thread_info info;
3489
        pthread_attr_t attr;
3490
#endif
3491
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3492
        init_task_state(ts);
3493
        new_stack = ts->stack;
3494
        /* we create a new CPU instance. */
3495
        new_env = cpu_copy(env);
3496
        /* Init regs that differ from the parent.  */
3497
        cpu_clone_regs(new_env, newsp);
3498
        new_env->opaque = ts;
3499
        ts->bprm = parent_ts->bprm;
3500
        ts->info = parent_ts->info;
3501
#if defined(USE_NPTL)
3502
        nptl_flags = flags;
3503
        flags &= ~CLONE_NPTL_FLAGS2;
3504

    
3505
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3506
            ts->child_tidptr = child_tidptr;
3507
        }
3508

    
3509
        if (nptl_flags & CLONE_SETTLS)
3510
            cpu_set_tls (new_env, newtls);
3511

    
3512
        /* Grab a mutex so that thread setup appears atomic.  */
3513
        pthread_mutex_lock(&clone_lock);
3514

    
3515
        memset(&info, 0, sizeof(info));
3516
        pthread_mutex_init(&info.mutex, NULL);
3517
        pthread_mutex_lock(&info.mutex);
3518
        pthread_cond_init(&info.cond, NULL);
3519
        info.env = new_env;
3520
        if (nptl_flags & CLONE_CHILD_SETTID)
3521
            info.child_tidptr = child_tidptr;
3522
        if (nptl_flags & CLONE_PARENT_SETTID)
3523
            info.parent_tidptr = parent_tidptr;
3524

    
3525
        ret = pthread_attr_init(&attr);
3526
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3527
        /* It is not safe to deliver signals until the child has finished
3528
           initializing, so temporarily block all signals.  */
3529
        sigfillset(&sigmask);
3530
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3531

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

    
3535
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3536
        pthread_attr_destroy(&attr);
3537
        if (ret == 0) {
3538
            /* Wait for the child to initialize.  */
3539
            pthread_cond_wait(&info.cond, &info.mutex);
3540
            ret = info.tid;
3541
            if (flags & CLONE_PARENT_SETTID)
3542
                put_user_u32(ret, parent_tidptr);
3543
        } else {
3544
            ret = -1;
3545
        }
3546
        pthread_mutex_unlock(&info.mutex);
3547
        pthread_cond_destroy(&info.cond);
3548
        pthread_mutex_destroy(&info.mutex);
3549
        pthread_mutex_unlock(&clone_lock);
3550
#else
3551
        if (flags & CLONE_NPTL_FLAGS2)
3552
            return -EINVAL;
3553
        /* This is probably going to die very quickly, but do it anyway.  */
3554
#ifdef __ia64__
3555
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3556
#else
3557
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3558
#endif
3559
#endif
3560
    } else {
3561
        /* if no CLONE_VM, we consider it is a fork */
3562
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3563
            return -EINVAL;
3564
        fork_start();
3565
        ret = fork();
3566
        if (ret == 0) {
3567
            /* Child Process.  */
3568
            cpu_clone_regs(env, newsp);
3569
            fork_end(1);
3570
#if defined(USE_NPTL)
3571
            /* There is a race condition here.  The parent process could
3572
               theoretically read the TID in the child process before the child
3573
               tid is set.  This would require using either ptrace
3574
               (not implemented) or having *_tidptr to point at a shared memory
3575
               mapping.  We can't repeat the spinlock hack used above because
3576
               the child process gets its own copy of the lock.  */
3577
            if (flags & CLONE_CHILD_SETTID)
3578
                put_user_u32(gettid(), child_tidptr);
3579
            if (flags & CLONE_PARENT_SETTID)
3580
                put_user_u32(gettid(), parent_tidptr);
3581
            ts = (TaskState *)env->opaque;
3582
            if (flags & CLONE_SETTLS)
3583
                cpu_set_tls (env, newtls);
3584
            if (flags & CLONE_CHILD_CLEARTID)
3585
                ts->child_tidptr = child_tidptr;
3586
#endif
3587
        } else {
3588
            fork_end(0);
3589
        }
3590
    }
3591
    return ret;
3592
}
3593

    
3594
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3595
{
3596
    struct flock fl;
3597
    struct target_flock *target_fl;
3598
    struct flock64 fl64;
3599
    struct target_flock64 *target_fl64;
3600
    abi_long ret;
3601

    
3602
    switch(cmd) {
3603
    case TARGET_F_GETLK:
3604
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3605
            return -TARGET_EFAULT;
3606
        fl.l_type = tswap16(target_fl->l_type);
3607
        fl.l_whence = tswap16(target_fl->l_whence);
3608
        fl.l_start = tswapl(target_fl->l_start);
3609
        fl.l_len = tswapl(target_fl->l_len);
3610
        fl.l_pid = tswapl(target_fl->l_pid);
3611
        unlock_user_struct(target_fl, arg, 0);
3612
        ret = get_errno(fcntl(fd, cmd, &fl));
3613
        if (ret == 0) {
3614
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3615
                return -TARGET_EFAULT;
3616
            target_fl->l_type = tswap16(fl.l_type);
3617
            target_fl->l_whence = tswap16(fl.l_whence);
3618
            target_fl->l_start = tswapl(fl.l_start);
3619
            target_fl->l_len = tswapl(fl.l_len);
3620
            target_fl->l_pid = tswapl(fl.l_pid);
3621
            unlock_user_struct(target_fl, arg, 1);
3622
        }
3623
        break;
3624

    
3625
    case TARGET_F_SETLK:
3626
    case TARGET_F_SETLKW:
3627
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3628
            return -TARGET_EFAULT;
3629
        fl.l_type = tswap16(target_fl->l_type);
3630
        fl.l_whence = tswap16(target_fl->l_whence);
3631
        fl.l_start = tswapl(target_fl->l_start);
3632
        fl.l_len = tswapl(target_fl->l_len);
3633
        fl.l_pid = tswapl(target_fl->l_pid);
3634
        unlock_user_struct(target_fl, arg, 0);
3635
        ret = get_errno(fcntl(fd, cmd, &fl));
3636
        break;
3637

    
3638
    case TARGET_F_GETLK64:
3639
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3640
            return -TARGET_EFAULT;
3641
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3642
        fl64.l_whence = tswap16(target_fl64->l_whence);
3643
        fl64.l_start = tswapl(target_fl64->l_start);
3644
        fl64.l_len = tswapl(target_fl64->l_len);
3645
        fl64.l_pid = tswap16(target_fl64->l_pid);
3646
        unlock_user_struct(target_fl64, arg, 0);
3647
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3648
        if (ret == 0) {
3649
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3650
                return -TARGET_EFAULT;
3651
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3652
            target_fl64->l_whence = tswap16(fl64.l_whence);
3653
            target_fl64->l_start = tswapl(fl64.l_start);
3654
            target_fl64->l_len = tswapl(fl64.l_len);
3655
            target_fl64->l_pid = tswapl(fl64.l_pid);
3656
            unlock_user_struct(target_fl64, arg, 1);
3657
        }
3658
        break;
3659
    case TARGET_F_SETLK64:
3660
    case TARGET_F_SETLKW64:
3661
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3662
            return -TARGET_EFAULT;
3663
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3664
        fl64.l_whence = tswap16(target_fl64->l_whence);
3665
        fl64.l_start = tswapl(target_fl64->l_start);
3666
        fl64.l_len = tswapl(target_fl64->l_len);
3667
        fl64.l_pid = tswap16(target_fl64->l_pid);
3668
        unlock_user_struct(target_fl64, arg, 0);
3669
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3670
        break;
3671

    
3672
    case F_GETFL:
3673
        ret = get_errno(fcntl(fd, cmd, arg));
3674
        if (ret >= 0) {
3675
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3676
        }
3677
        break;
3678

    
3679
    case F_SETFL:
3680
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3681
        break;
3682

    
3683
    default:
3684
        ret = get_errno(fcntl(fd, cmd, arg));
3685
        break;
3686
    }
3687
    return ret;
3688
}
3689

    
3690
#ifdef USE_UID16
3691

    
3692
static inline int high2lowuid(int uid)
3693
{
3694
    if (uid > 65535)
3695
        return 65534;
3696
    else
3697
        return uid;
3698
}
3699

    
3700
static inline int high2lowgid(int gid)
3701
{
3702
    if (gid > 65535)
3703
        return 65534;
3704
    else
3705
        return gid;
3706
}
3707

    
3708
static inline int low2highuid(int uid)
3709
{
3710
    if ((int16_t)uid == -1)
3711
        return -1;
3712
    else
3713
        return uid;
3714
}
3715

    
3716
static inline int low2highgid(int gid)
3717
{
3718
    if ((int16_t)gid == -1)
3719
        return -1;
3720
    else
3721
        return gid;
3722
}
3723

    
3724
#endif /* USE_UID16 */
3725

    
3726
void syscall_init(void)
3727
{
3728
    IOCTLEntry *ie;
3729
    const argtype *arg_type;
3730
    int size;
3731
    int i;
3732

    
3733
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3734
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3735
#include "syscall_types.h"
3736
#undef STRUCT
3737
#undef STRUCT_SPECIAL
3738

    
3739
    /* we patch the ioctl size if necessary. We rely on the fact that
3740
       no ioctl has all the bits at '1' in the size field */
3741
    ie = ioctl_entries;
3742
    while (ie->target_cmd != 0) {
3743
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3744
            TARGET_IOC_SIZEMASK) {
3745
            arg_type = ie->arg_type;
3746
            if (arg_type[0] != TYPE_PTR) {
3747
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3748
                        ie->target_cmd);
3749
                exit(1);
3750
            }
3751
            arg_type++;
3752
            size = thunk_type_size(arg_type, 0);
3753
            ie->target_cmd = (ie->target_cmd &
3754
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3755
                (size << TARGET_IOC_SIZESHIFT);
3756
        }
3757

    
3758
        /* Build target_to_host_errno_table[] table from
3759
         * host_to_target_errno_table[]. */
3760
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3761
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3762

    
3763
        /* automatic consistency check if same arch */
3764
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3765
    (defined(__x86_64__) && defined(TARGET_X86_64))
3766
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3767
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3768
                    ie->name, ie->target_cmd, ie->host_cmd);
3769
        }
3770
#endif
3771
        ie++;
3772
    }
3773
}
3774

    
3775
#if TARGET_ABI_BITS == 32
3776
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3777
{
3778
#ifdef TARGET_WORDS_BIGENDIAN
3779
    return ((uint64_t)word0 << 32) | word1;
3780
#else
3781
    return ((uint64_t)word1 << 32) | word0;
3782
#endif
3783
}
3784
#else /* TARGET_ABI_BITS == 32 */
3785
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3786
{
3787
    return word0;
3788
}
3789
#endif /* TARGET_ABI_BITS != 32 */
3790

    
3791
#ifdef TARGET_NR_truncate64
3792
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3793
                                         abi_long arg2,
3794
                                         abi_long arg3,
3795
                                         abi_long arg4)
3796
{
3797
#ifdef TARGET_ARM
3798
    if (((CPUARMState *)cpu_env)->eabi)
3799
      {
3800
        arg2 = arg3;
3801
        arg3 = arg4;
3802
      }
3803
#endif
3804
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3805
}
3806
#endif
3807

    
3808
#ifdef TARGET_NR_ftruncate64
3809
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3810
                                          abi_long arg2,
3811
                                          abi_long arg3,
3812
                                          abi_long arg4)
3813
{
3814
#ifdef TARGET_ARM
3815
    if (((CPUARMState *)cpu_env)->eabi)
3816
      {
3817
        arg2 = arg3;
3818
        arg3 = arg4;
3819
      }
3820
#endif
3821
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3822
}
3823
#endif
3824

    
3825
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3826
                                               abi_ulong target_addr)
3827
{
3828
    struct target_timespec *target_ts;
3829

    
3830
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3831
        return -TARGET_EFAULT;
3832
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3833
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3834
    unlock_user_struct(target_ts, target_addr, 0);
3835
    return 0;
3836
}
3837

    
3838
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3839
                                               struct timespec *host_ts)
3840
{
3841
    struct target_timespec *target_ts;
3842

    
3843
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3844
        return -TARGET_EFAULT;
3845
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3846
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3847
    unlock_user_struct(target_ts, target_addr, 1);
3848
    return 0;
3849
}
3850

    
3851
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3852
static inline abi_long host_to_target_stat64(void *cpu_env,
3853
                                             abi_ulong target_addr,
3854
                                             struct stat *host_st)
3855
{
3856
#ifdef TARGET_ARM
3857
    if (((CPUARMState *)cpu_env)->eabi) {
3858
        struct target_eabi_stat64 *target_st;
3859

    
3860
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3861
            return -TARGET_EFAULT;
3862
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3863
        __put_user(host_st->st_dev, &target_st->st_dev);
3864
        __put_user(host_st->st_ino, &target_st->st_ino);
3865
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3866
        __put_user(host_st->st_ino, &target_st->__st_ino);
3867
#endif
3868
        __put_user(host_st->st_mode, &target_st->st_mode);
3869
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3870
        __put_user(host_st->st_uid, &target_st->st_uid);
3871
        __put_user(host_st->st_gid, &target_st->st_gid);
3872
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3873
        __put_user(host_st->st_size, &target_st->st_size);
3874
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3875
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3876
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3877
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3878
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3879
        unlock_user_struct(target_st, target_addr, 1);
3880
    } else
3881
#endif
3882
    {
3883
#if TARGET_LONG_BITS == 64
3884
        struct target_stat *target_st;
3885
#else
3886
        struct target_stat64 *target_st;
3887
#endif
3888

    
3889
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3890
            return -TARGET_EFAULT;
3891
        memset(target_st, 0, sizeof(*target_st));
3892
        __put_user(host_st->st_dev, &target_st->st_dev);
3893
        __put_user(host_st->st_ino, &target_st->st_ino);
3894
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3895
        __put_user(host_st->st_ino, &target_st->__st_ino);
3896
#endif
3897
        __put_user(host_st->st_mode, &target_st->st_mode);
3898
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3899
        __put_user(host_st->st_uid, &target_st->st_uid);
3900
        __put_user(host_st->st_gid, &target_st->st_gid);
3901
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3902
        /* XXX: better use of kernel struct */
3903
        __put_user(host_st->st_size, &target_st->st_size);
3904
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3905
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3906
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3907
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3908
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3909
        unlock_user_struct(target_st, target_addr, 1);
3910
    }
3911

    
3912
    return 0;
3913
}
3914
#endif
3915

    
3916
#if defined(USE_NPTL)
3917
/* ??? Using host futex calls even when target atomic operations
3918
   are not really atomic probably breaks things.  However implementing
3919
   futexes locally would make futexes shared between multiple processes
3920
   tricky.  However they're probably useless because guest atomic
3921
   operations won't work either.  */
3922
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3923
                    target_ulong uaddr2, int val3)
3924
{
3925
    struct timespec ts, *pts;
3926

    
3927
    /* ??? We assume FUTEX_* constants are the same on both host
3928
       and target.  */
3929
#ifdef FUTEX_CMD_MASK
3930
    switch ((op&FUTEX_CMD_MASK)) {
3931
#else
3932
    switch (op) {
3933
#endif
3934
    case FUTEX_WAIT:
3935
        if (timeout) {
3936
            pts = &ts;
3937
            target_to_host_timespec(pts, timeout);
3938
        } else {
3939
            pts = NULL;
3940
        }
3941
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
3942
                         pts, NULL, 0));
3943
    case FUTEX_WAKE:
3944
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
3945
    case FUTEX_WAKE_OP:
3946
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, g2h(uaddr2), val3 ));
3947
    case FUTEX_FD:
3948
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
3949
    case FUTEX_REQUEUE:
3950
        return get_errno(sys_futex(g2h(uaddr), op, val,
3951
                         NULL, g2h(uaddr2), 0));
3952
    case FUTEX_CMP_REQUEUE:
3953
        return get_errno(sys_futex(g2h(uaddr), op, val,
3954
                         NULL, g2h(uaddr2), tswap32(val3)));
3955
    default:
3956
        return -TARGET_ENOSYS;
3957
    }
3958
}
3959
#endif
3960

    
3961
/* Map host to target signal numbers for the wait family of syscalls.
3962
   Assume all other status bits are the same.  */
3963
static int host_to_target_waitstatus(int status)
3964
{
3965
    if (WIFSIGNALED(status)) {
3966
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
3967
    }
3968
    if (WIFSTOPPED(status)) {
3969
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
3970
               | (status & 0xff);
3971
    }
3972
    return status;
3973
}
3974

    
3975
int get_osversion(void)
3976
{
3977
    static int osversion;
3978
    struct new_utsname buf;
3979
    const char *s;
3980
    int i, n, tmp;
3981
    if (osversion)
3982
        return osversion;
3983
    if (qemu_uname_release && *qemu_uname_release) {
3984
        s = qemu_uname_release;
3985
    } else {
3986
        if (sys_uname(&buf))
3987
            return 0;
3988
        s = buf.release;
3989
    }
3990
    tmp = 0;
3991
    for (i = 0; i < 3; i++) {
3992
        n = 0;
3993
        while (*s >= '0' && *s <= '9') {
3994
            n *= 10;
3995
            n += *s - '0';
3996
            s++;
3997
        }
3998
        tmp = (tmp << 8) + n;
3999
        if (*s == '.')
4000
            s++;
4001
    }
4002
    osversion = tmp;
4003
    return osversion;
4004
}
4005

    
4006
/* do_syscall() should always have a single exit point at the end so
4007
   that actions, such as logging of syscall results, can be performed.
4008
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4009
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4010
                    abi_long arg2, abi_long arg3, abi_long arg4,
4011
                    abi_long arg5, abi_long arg6)
4012
{
4013
    abi_long ret;
4014
    struct stat st;
4015
    struct statfs stfs;
4016
    void *p;
4017

    
4018
#ifdef DEBUG
4019
    gemu_log("syscall %d", num);
4020
#endif
4021
    if(do_strace)
4022
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4023

    
4024
    switch(num) {
4025
    case TARGET_NR_exit:
4026
#ifdef USE_NPTL
4027
      /* In old applications this may be used to implement _exit(2).
4028
         However in threaded applictions it is used for thread termination,
4029
         and _exit_group is used for application termination.
4030
         Do thread termination if we have more then one thread.  */
4031
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4032
         be disabling signals.  */
4033
      if (first_cpu->next_cpu) {
4034
          TaskState *ts;
4035
          CPUState **lastp;
4036
          CPUState *p;
4037

    
4038
          cpu_list_lock();
4039
          lastp = &first_cpu;
4040
          p = first_cpu;
4041
          while (p && p != (CPUState *)cpu_env) {
4042
              lastp = &p->next_cpu;
4043
              p = p->next_cpu;
4044
          }
4045
          /* If we didn't find the CPU for this thread then something is
4046
             horribly wrong.  */
4047
          if (!p)
4048
              abort();
4049
          /* Remove the CPU from the list.  */
4050
          *lastp = p->next_cpu;
4051
          cpu_list_unlock();
4052
          ts = ((CPUState *)cpu_env)->opaque;
4053
          if (ts->child_tidptr) {
4054
              put_user_u32(0, ts->child_tidptr);
4055
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4056
                        NULL, NULL, 0);
4057
          }
4058
          /* TODO: Free CPU state.  */
4059
          pthread_exit(NULL);
4060
      }
4061
#endif
4062
#ifdef HAVE_GPROF
4063
        _mcleanup();
4064
#endif
4065
        gdb_exit(cpu_env, arg1);
4066
        _exit(arg1);
4067
        ret = 0; /* avoid warning */
4068
        break;
4069
    case TARGET_NR_read:
4070
        if (arg3 == 0)
4071
            ret = 0;
4072
        else {
4073
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4074
                goto efault;
4075
            ret = get_errno(read(arg1, p, arg3));
4076
            unlock_user(p, arg2, ret);
4077
        }
4078
        break;
4079
    case TARGET_NR_write:
4080
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4081
            goto efault;
4082
        ret = get_errno(write(arg1, p, arg3));
4083
        unlock_user(p, arg2, 0);
4084
        break;
4085
    case TARGET_NR_open:
4086
        if (!(p = lock_user_string(arg1)))
4087
            goto efault;
4088
        ret = get_errno(open(path(p),
4089
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4090
                             arg3));
4091
        unlock_user(p, arg1, 0);
4092
        break;
4093
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4094
    case TARGET_NR_openat:
4095
        if (!(p = lock_user_string(arg2)))
4096
            goto efault;
4097
        ret = get_errno(sys_openat(arg1,
4098
                                   path(p),
4099
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4100
                                   arg4));
4101
        unlock_user(p, arg2, 0);
4102
        break;
4103
#endif
4104
    case TARGET_NR_close:
4105
        ret = get_errno(close(arg1));
4106
        break;
4107
    case TARGET_NR_brk:
4108
        ret = do_brk(arg1);
4109
        break;
4110
    case TARGET_NR_fork:
4111
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4112
        break;
4113
#ifdef TARGET_NR_waitpid
4114
    case TARGET_NR_waitpid:
4115
        {
4116
            int status;
4117
            ret = get_errno(waitpid(arg1, &status, arg3));
4118
            if (!is_error(ret) && arg2
4119
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4120
                goto efault;
4121
        }
4122
        break;
4123
#endif
4124
#ifdef TARGET_NR_waitid
4125
    case TARGET_NR_waitid:
4126
        {
4127
            siginfo_t info;
4128
            info.si_pid = 0;
4129
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4130
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4131
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4132
                    goto efault;
4133
                host_to_target_siginfo(p, &info);
4134
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4135
            }
4136
        }
4137
        break;
4138
#endif
4139
#ifdef TARGET_NR_creat /* not on alpha */
4140
    case TARGET_NR_creat:
4141
        if (!(p = lock_user_string(arg1)))
4142
            goto efault;
4143
        ret = get_errno(creat(p, arg2));
4144
        unlock_user(p, arg1, 0);
4145
        break;
4146
#endif
4147
    case TARGET_NR_link:
4148
        {
4149
            void * p2;
4150
            p = lock_user_string(arg1);
4151
            p2 = lock_user_string(arg2);
4152
            if (!p || !p2)
4153
                ret = -TARGET_EFAULT;
4154
            else
4155
                ret = get_errno(link(p, p2));
4156
            unlock_user(p2, arg2, 0);
4157
            unlock_user(p, arg1, 0);
4158
        }
4159
        break;
4160
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4161
    case TARGET_NR_linkat:
4162
        {
4163
            void * p2 = NULL;
4164
            if (!arg2 || !arg4)
4165
                goto efault;
4166
            p  = lock_user_string(arg2);
4167
            p2 = lock_user_string(arg4);
4168
            if (!p || !p2)
4169
                ret = -TARGET_EFAULT;
4170
            else
4171
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4172
            unlock_user(p, arg2, 0);
4173
            unlock_user(p2, arg4, 0);
4174
        }
4175
        break;
4176
#endif
4177
    case TARGET_NR_unlink:
4178
        if (!(p = lock_user_string(arg1)))
4179
            goto efault;
4180
        ret = get_errno(unlink(p));
4181
        unlock_user(p, arg1, 0);
4182
        break;
4183
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4184
    case TARGET_NR_unlinkat:
4185
        if (!(p = lock_user_string(arg2)))
4186
            goto efault;
4187
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4188
        unlock_user(p, arg2, 0);
4189
        break;
4190
#endif
4191
    case TARGET_NR_execve:
4192
        {
4193
            char **argp, **envp;
4194
            int argc, envc;
4195
            abi_ulong gp;
4196
            abi_ulong guest_argp;
4197
            abi_ulong guest_envp;
4198
            abi_ulong addr;
4199
            char **q;
4200

    
4201
            argc = 0;
4202
            guest_argp = arg2;
4203
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4204
                if (get_user_ual(addr, gp))
4205
                    goto efault;
4206
                if (!addr)
4207
                    break;
4208
                argc++;
4209
            }
4210
            envc = 0;
4211
            guest_envp = arg3;
4212
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4213
                if (get_user_ual(addr, gp))
4214
                    goto efault;
4215
                if (!addr)
4216
                    break;
4217
                envc++;
4218
            }
4219

    
4220
            argp = alloca((argc + 1) * sizeof(void *));
4221
            envp = alloca((envc + 1) * sizeof(void *));
4222

    
4223
            for (gp = guest_argp, q = argp; gp;
4224
                  gp += sizeof(abi_ulong), q++) {
4225
                if (get_user_ual(addr, gp))
4226
                    goto execve_efault;
4227
                if (!addr)
4228
                    break;
4229
                if (!(*q = lock_user_string(addr)))
4230
                    goto execve_efault;
4231
            }
4232
            *q = NULL;
4233

    
4234
            for (gp = guest_envp, q = envp; gp;
4235
                  gp += sizeof(abi_ulong), q++) {
4236
                if (get_user_ual(addr, gp))
4237
                    goto execve_efault;
4238
                if (!addr)
4239
                    break;
4240
                if (!(*q = lock_user_string(addr)))
4241
                    goto execve_efault;
4242
            }
4243
            *q = NULL;
4244

    
4245
            if (!(p = lock_user_string(arg1)))
4246
                goto execve_efault;
4247
            ret = get_errno(execve(p, argp, envp));
4248
            unlock_user(p, arg1, 0);
4249

    
4250
            goto execve_end;
4251

    
4252
        execve_efault:
4253
            ret = -TARGET_EFAULT;
4254

    
4255
        execve_end:
4256
            for (gp = guest_argp, q = argp; *q;
4257
                  gp += sizeof(abi_ulong), q++) {
4258
                if (get_user_ual(addr, gp)
4259
                    || !addr)
4260
                    break;
4261
                unlock_user(*q, addr, 0);
4262
            }
4263
            for (gp = guest_envp, q = envp; *q;
4264
                  gp += sizeof(abi_ulong), q++) {
4265
                if (get_user_ual(addr, gp)
4266
                    || !addr)
4267
                    break;
4268
                unlock_user(*q, addr, 0);
4269
            }
4270
        }
4271
        break;
4272
    case TARGET_NR_chdir:
4273
        if (!(p = lock_user_string(arg1)))
4274
            goto efault;
4275
        ret = get_errno(chdir(p));
4276
        unlock_user(p, arg1, 0);
4277
        break;
4278
#ifdef TARGET_NR_time
4279
    case TARGET_NR_time:
4280
        {
4281
            time_t host_time;
4282
            ret = get_errno(time(&host_time));
4283
            if (!is_error(ret)
4284
                && arg1
4285
                && put_user_sal(host_time, arg1))
4286
                goto efault;
4287
        }
4288
        break;
4289
#endif
4290
    case TARGET_NR_mknod:
4291
        if (!(p = lock_user_string(arg1)))
4292
            goto efault;
4293
        ret = get_errno(mknod(p, arg2, arg3));
4294
        unlock_user(p, arg1, 0);
4295
        break;
4296
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4297
    case TARGET_NR_mknodat:
4298
        if (!(p = lock_user_string(arg2)))
4299
            goto efault;
4300
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4301
        unlock_user(p, arg2, 0);
4302
        break;
4303
#endif
4304
    case TARGET_NR_chmod:
4305
        if (!(p = lock_user_string(arg1)))
4306
            goto efault;
4307
        ret = get_errno(chmod(p, arg2));
4308
        unlock_user(p, arg1, 0);
4309
        break;
4310
#ifdef TARGET_NR_break
4311
    case TARGET_NR_break:
4312
        goto unimplemented;
4313
#endif
4314
#ifdef TARGET_NR_oldstat
4315
    case TARGET_NR_oldstat:
4316
        goto unimplemented;
4317
#endif
4318
    case TARGET_NR_lseek:
4319
        ret = get_errno(lseek(arg1, arg2, arg3));
4320
        break;
4321
#ifdef TARGET_NR_getxpid
4322
    case TARGET_NR_getxpid:
4323
#else
4324
    case TARGET_NR_getpid:
4325
#endif
4326
        ret = get_errno(getpid());
4327
        break;
4328
    case TARGET_NR_mount:
4329
                {
4330
                        /* need to look at the data field */
4331
                        void *p2, *p3;
4332
                        p = lock_user_string(arg1);
4333
                        p2 = lock_user_string(arg2);
4334
                        p3 = lock_user_string(arg3);
4335
                        if (!p || !p2 || !p3)
4336
                            ret = -TARGET_EFAULT;
4337
                        else
4338
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4339
                             * do that since it's not guaranteed to be a NULL-terminated
4340
                             * string.
4341
                             */
4342
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4343
                        unlock_user(p, arg1, 0);
4344
                        unlock_user(p2, arg2, 0);
4345
                        unlock_user(p3, arg3, 0);
4346
                        break;
4347
                }
4348
#ifdef TARGET_NR_umount
4349
    case TARGET_NR_umount:
4350
        if (!(p = lock_user_string(arg1)))
4351
            goto efault;
4352
        ret = get_errno(umount(p));
4353
        unlock_user(p, arg1, 0);
4354
        break;
4355
#endif
4356
#ifdef TARGET_NR_stime /* not on alpha */
4357
    case TARGET_NR_stime:
4358
        {
4359
            time_t host_time;
4360
            if (get_user_sal(host_time, arg1))
4361
                goto efault;
4362
            ret = get_errno(stime(&host_time));
4363
        }
4364
        break;
4365
#endif
4366
    case TARGET_NR_ptrace:
4367
        goto unimplemented;
4368
#ifdef TARGET_NR_alarm /* not on alpha */
4369
    case TARGET_NR_alarm:
4370
        ret = alarm(arg1);
4371
        break;
4372
#endif
4373
#ifdef TARGET_NR_oldfstat
4374
    case TARGET_NR_oldfstat:
4375
        goto unimplemented;
4376
#endif
4377
#ifdef TARGET_NR_pause /* not on alpha */
4378
    case TARGET_NR_pause:
4379
        ret = get_errno(pause());
4380
        break;
4381
#endif
4382
#ifdef TARGET_NR_utime
4383
    case TARGET_NR_utime:
4384
        {
4385
            struct utimbuf tbuf, *host_tbuf;
4386
            struct target_utimbuf *target_tbuf;
4387
            if (arg2) {
4388
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4389
                    goto efault;
4390
                tbuf.actime = tswapl(target_tbuf->actime);
4391
                tbuf.modtime = tswapl(target_tbuf->modtime);
4392
                unlock_user_struct(target_tbuf, arg2, 0);
4393
                host_tbuf = &tbuf;
4394
            } else {
4395
                host_tbuf = NULL;
4396
            }
4397
            if (!(p = lock_user_string(arg1)))
4398
                goto efault;
4399
            ret = get_errno(utime(p, host_tbuf));
4400
            unlock_user(p, arg1, 0);
4401
        }
4402
        break;
4403
#endif
4404
    case TARGET_NR_utimes:
4405
        {
4406
            struct timeval *tvp, tv[2];
4407
            if (arg2) {
4408
                if (copy_from_user_timeval(&tv[0], arg2)
4409
                    || copy_from_user_timeval(&tv[1],
4410
                                              arg2 + sizeof(struct target_timeval)))
4411
                    goto efault;
4412
                tvp = tv;
4413
            } else {
4414
                tvp = NULL;
4415
            }
4416
            if (!(p = lock_user_string(arg1)))
4417
                goto efault;
4418
            ret = get_errno(utimes(p, tvp));
4419
            unlock_user(p, arg1, 0);
4420
        }
4421
        break;
4422
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4423
    case TARGET_NR_futimesat:
4424
        {
4425
            struct timeval *tvp, tv[2];
4426
            if (arg3) {
4427
                if (copy_from_user_timeval(&tv[0], arg3)
4428
                    || copy_from_user_timeval(&tv[1],
4429
                                              arg3 + sizeof(struct target_timeval)))
4430
                    goto efault;
4431
                tvp = tv;
4432
            } else {
4433
                tvp = NULL;
4434
            }
4435
            if (!(p = lock_user_string(arg2)))
4436
                goto efault;
4437
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4438
            unlock_user(p, arg2, 0);
4439
        }
4440
        break;
4441
#endif
4442
#ifdef TARGET_NR_stty
4443
    case TARGET_NR_stty:
4444
        goto unimplemented;
4445
#endif
4446
#ifdef TARGET_NR_gtty
4447
    case TARGET_NR_gtty:
4448
        goto unimplemented;
4449
#endif
4450
    case TARGET_NR_access:
4451
        if (!(p = lock_user_string(arg1)))
4452
            goto efault;
4453
        ret = get_errno(access(p, arg2));
4454
        unlock_user(p, arg1, 0);
4455
        break;
4456
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4457
    case TARGET_NR_faccessat:
4458
        if (!(p = lock_user_string(arg2)))
4459
            goto efault;
4460
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4461
        unlock_user(p, arg2, 0);
4462
        break;
4463
#endif
4464
#ifdef TARGET_NR_nice /* not on alpha */
4465
    case TARGET_NR_nice:
4466
        ret = get_errno(nice(arg1));
4467
        break;
4468
#endif
4469
#ifdef TARGET_NR_ftime
4470
    case TARGET_NR_ftime:
4471
        goto unimplemented;
4472
#endif
4473
    case TARGET_NR_sync:
4474
        sync();
4475
        ret = 0;
4476
        break;
4477
    case TARGET_NR_kill:
4478
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4479
        break;
4480
    case TARGET_NR_rename:
4481
        {
4482
            void *p2;
4483
            p = lock_user_string(arg1);
4484
            p2 = lock_user_string(arg2);
4485
            if (!p || !p2)
4486
                ret = -TARGET_EFAULT;
4487
            else
4488
                ret = get_errno(rename(p, p2));
4489
            unlock_user(p2, arg2, 0);
4490
            unlock_user(p, arg1, 0);
4491
        }
4492
        break;
4493
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4494
    case TARGET_NR_renameat:
4495
        {
4496
            void *p2;
4497
            p  = lock_user_string(arg2);
4498
            p2 = lock_user_string(arg4);
4499
            if (!p || !p2)
4500
                ret = -TARGET_EFAULT;
4501
            else
4502
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4503
            unlock_user(p2, arg4, 0);
4504
            unlock_user(p, arg2, 0);
4505
        }
4506
        break;
4507
#endif
4508
    case TARGET_NR_mkdir:
4509
        if (!(p = lock_user_string(arg1)))
4510
            goto efault;
4511
        ret = get_errno(mkdir(p, arg2));
4512
        unlock_user(p, arg1, 0);
4513
        break;
4514
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4515
    case TARGET_NR_mkdirat:
4516
        if (!(p = lock_user_string(arg2)))
4517
            goto efault;
4518
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4519
        unlock_user(p, arg2, 0);
4520
        break;
4521
#endif
4522
    case TARGET_NR_rmdir:
4523
        if (!(p = lock_user_string(arg1)))
4524
            goto efault;
4525
        ret = get_errno(rmdir(p));
4526
        unlock_user(p, arg1, 0);
4527
        break;
4528
    case TARGET_NR_dup:
4529
        ret = get_errno(dup(arg1));
4530
        break;
4531
    case TARGET_NR_pipe:
4532
        {
4533
            int host_pipe[2];
4534
            ret = get_errno(pipe(host_pipe));
4535
            if (!is_error(ret)) {
4536
#if defined(TARGET_MIPS)
4537
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4538
                env->active_tc.gpr[3] = host_pipe[1];
4539
                ret = host_pipe[0];
4540
#elif defined(TARGET_SH4)
4541
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4542
                ret = host_pipe[0];
4543
#else
4544
                if (put_user_s32(host_pipe[0], arg1)
4545
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4546
                    goto efault;
4547
#endif
4548
            }
4549
        }
4550
        break;
4551
    case TARGET_NR_times:
4552
        {
4553
            struct target_tms *tmsp;
4554
            struct tms tms;
4555
            ret = get_errno(times(&tms));
4556
            if (arg1) {
4557
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4558
                if (!tmsp)
4559
                    goto efault;
4560
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4561
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4562
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4563
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4564
            }
4565
            if (!is_error(ret))
4566
                ret = host_to_target_clock_t(ret);
4567
        }
4568
        break;
4569
#ifdef TARGET_NR_prof
4570
    case TARGET_NR_prof:
4571
        goto unimplemented;
4572
#endif
4573
#ifdef TARGET_NR_signal
4574
    case TARGET_NR_signal:
4575
        goto unimplemented;
4576
#endif
4577
    case TARGET_NR_acct:
4578
        if (arg1 == 0) {
4579
            ret = get_errno(acct(NULL));
4580
        } else {
4581
            if (!(p = lock_user_string(arg1)))
4582
                goto efault;
4583
            ret = get_errno(acct(path(p)));
4584
            unlock_user(p, arg1, 0);
4585
        }
4586
        break;
4587
#ifdef TARGET_NR_umount2 /* not on alpha */
4588
    case TARGET_NR_umount2:
4589
        if (!(p = lock_user_string(arg1)))
4590
            goto efault;
4591
        ret = get_errno(umount2(p, arg2));
4592
        unlock_user(p, arg1, 0);
4593
        break;
4594
#endif
4595
#ifdef TARGET_NR_lock
4596
    case TARGET_NR_lock:
4597
        goto unimplemented;
4598
#endif
4599
    case TARGET_NR_ioctl:
4600
        ret = do_ioctl(arg1, arg2, arg3);
4601
        break;
4602
    case TARGET_NR_fcntl:
4603
        ret = do_fcntl(arg1, arg2, arg3);
4604
        break;
4605
#ifdef TARGET_NR_mpx
4606
    case TARGET_NR_mpx:
4607
        goto unimplemented;
4608
#endif
4609
    case TARGET_NR_setpgid:
4610
        ret = get_errno(setpgid(arg1, arg2));
4611
        break;
4612
#ifdef TARGET_NR_ulimit
4613
    case TARGET_NR_ulimit:
4614
        goto unimplemented;
4615
#endif
4616
#ifdef TARGET_NR_oldolduname
4617
    case TARGET_NR_oldolduname:
4618
        goto unimplemented;
4619
#endif
4620
    case TARGET_NR_umask:
4621
        ret = get_errno(umask(arg1));
4622
        break;
4623
    case TARGET_NR_chroot:
4624
        if (!(p = lock_user_string(arg1)))
4625
            goto efault;
4626
        ret = get_errno(chroot(p));
4627
        unlock_user(p, arg1, 0);
4628
        break;
4629
    case TARGET_NR_ustat:
4630
        goto unimplemented;
4631
    case TARGET_NR_dup2:
4632
        ret = get_errno(dup2(arg1, arg2));
4633
        break;
4634
#ifdef TARGET_NR_getppid /* not on alpha */
4635
    case TARGET_NR_getppid:
4636
        ret = get_errno(getppid());
4637
        break;
4638
#endif
4639
    case TARGET_NR_getpgrp:
4640
        ret = get_errno(getpgrp());
4641
        break;
4642
    case TARGET_NR_setsid:
4643
        ret = get_errno(setsid());
4644
        break;
4645
#ifdef TARGET_NR_sigaction
4646
    case TARGET_NR_sigaction:
4647
        {
4648
#if !defined(TARGET_MIPS)
4649
            struct target_old_sigaction *old_act;
4650
            struct target_sigaction act, oact, *pact;
4651
            if (arg2) {
4652
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4653
                    goto efault;
4654
                act._sa_handler = old_act->_sa_handler;
4655
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4656
                act.sa_flags = old_act->sa_flags;
4657
                act.sa_restorer = old_act->sa_restorer;
4658
                unlock_user_struct(old_act, arg2, 0);
4659
                pact = &act;
4660
            } else {
4661
                pact = NULL;
4662
            }
4663
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4664
            if (!is_error(ret) && arg3) {
4665
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4666
                    goto efault;
4667
                old_act->_sa_handler = oact._sa_handler;
4668
                old_act->sa_mask = oact.sa_mask.sig[0];
4669
                old_act->sa_flags = oact.sa_flags;
4670
                old_act->sa_restorer = oact.sa_restorer;
4671
                unlock_user_struct(old_act, arg3, 1);
4672
            }
4673
#else
4674
            struct target_sigaction act, oact, *pact, *old_act;
4675

    
4676
            if (arg2) {
4677
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4678
                    goto efault;
4679
                act._sa_handler = old_act->_sa_handler;
4680
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4681
                act.sa_flags = old_act->sa_flags;
4682
                unlock_user_struct(old_act, arg2, 0);
4683
                pact = &act;
4684
            } else {
4685
                pact = NULL;
4686
            }
4687

    
4688
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4689

    
4690
            if (!is_error(ret) && arg3) {
4691
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4692
                    goto efault;
4693
                old_act->_sa_handler = oact._sa_handler;
4694
                old_act->sa_flags = oact.sa_flags;
4695
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4696
                old_act->sa_mask.sig[1] = 0;
4697
                old_act->sa_mask.sig[2] = 0;
4698
                old_act->sa_mask.sig[3] = 0;
4699
                unlock_user_struct(old_act, arg3, 1);
4700
            }
4701
#endif
4702
        }
4703
        break;
4704
#endif
4705
    case TARGET_NR_rt_sigaction:
4706
        {
4707
            struct target_sigaction *act;
4708
            struct target_sigaction *oact;
4709

    
4710
            if (arg2) {
4711
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4712
                    goto efault;
4713
            } else
4714
                act = NULL;
4715
            if (arg3) {
4716
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4717
                    ret = -TARGET_EFAULT;
4718
                    goto rt_sigaction_fail;
4719
                }
4720
            } else
4721
                oact = NULL;
4722
            ret = get_errno(do_sigaction(arg1, act, oact));
4723
        rt_sigaction_fail:
4724
            if (act)
4725
                unlock_user_struct(act, arg2, 0);
4726
            if (oact)
4727
                unlock_user_struct(oact, arg3, 1);
4728
        }
4729
        break;
4730
#ifdef TARGET_NR_sgetmask /* not on alpha */
4731
    case TARGET_NR_sgetmask:
4732
        {
4733
            sigset_t cur_set;
4734
            abi_ulong target_set;
4735
            sigprocmask(0, NULL, &cur_set);
4736
            host_to_target_old_sigset(&target_set, &cur_set);
4737
            ret = target_set;
4738
        }
4739
        break;
4740
#endif
4741
#ifdef TARGET_NR_ssetmask /* not on alpha */
4742
    case TARGET_NR_ssetmask:
4743
        {
4744
            sigset_t set, oset, cur_set;
4745
            abi_ulong target_set = arg1;
4746
            sigprocmask(0, NULL, &cur_set);
4747
            target_to_host_old_sigset(&set, &target_set);
4748
            sigorset(&set, &set, &cur_set);
4749
            sigprocmask(SIG_SETMASK, &set, &oset);
4750
            host_to_target_old_sigset(&target_set, &oset);
4751
            ret = target_set;
4752
        }
4753
        break;
4754
#endif
4755
#ifdef TARGET_NR_sigprocmask
4756
    case TARGET_NR_sigprocmask:
4757
        {
4758
            int how = arg1;
4759
            sigset_t set, oldset, *set_ptr;
4760

    
4761
            if (arg2) {
4762
                switch(how) {
4763
                case TARGET_SIG_BLOCK:
4764
                    how = SIG_BLOCK;
4765
                    break;
4766
                case TARGET_SIG_UNBLOCK:
4767
                    how = SIG_UNBLOCK;
4768
                    break;
4769
                case TARGET_SIG_SETMASK:
4770
                    how = SIG_SETMASK;
4771
                    break;
4772
                default:
4773
                    ret = -TARGET_EINVAL;
4774
                    goto fail;
4775
                }
4776
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4777
                    goto efault;
4778
                target_to_host_old_sigset(&set, p);
4779
                unlock_user(p, arg2, 0);
4780
                set_ptr = &set;
4781
            } else {
4782
                how = 0;
4783
                set_ptr = NULL;
4784
            }
4785
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4786
            if (!is_error(ret) && arg3) {
4787
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4788
                    goto efault;
4789
                host_to_target_old_sigset(p, &oldset);
4790
                unlock_user(p, arg3, sizeof(target_sigset_t));
4791
            }
4792
        }
4793
        break;
4794
#endif
4795
    case TARGET_NR_rt_sigprocmask:
4796
        {
4797
            int how = arg1;
4798
            sigset_t set, oldset, *set_ptr;
4799

    
4800
            if (arg2) {
4801
                switch(how) {
4802
                case TARGET_SIG_BLOCK:
4803
                    how = SIG_BLOCK;
4804
                    break;
4805
                case TARGET_SIG_UNBLOCK:
4806
                    how = SIG_UNBLOCK;
4807
                    break;
4808
                case TARGET_SIG_SETMASK:
4809
                    how = SIG_SETMASK;
4810
                    break;
4811
                default:
4812
                    ret = -TARGET_EINVAL;
4813
                    goto fail;
4814
                }
4815
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4816
                    goto efault;
4817
                target_to_host_sigset(&set, p);
4818
                unlock_user(p, arg2, 0);
4819
                set_ptr = &set;
4820
            } else {
4821
                how = 0;
4822
                set_ptr = NULL;
4823
            }
4824
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4825
            if (!is_error(ret) && arg3) {
4826
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4827
                    goto efault;
4828
                host_to_target_sigset(p, &oldset);
4829
                unlock_user(p, arg3, sizeof(target_sigset_t));
4830
            }
4831
        }
4832
        break;
4833
#ifdef TARGET_NR_sigpending
4834
    case TARGET_NR_sigpending:
4835
        {
4836
            sigset_t set;
4837
            ret = get_errno(sigpending(&set));
4838
            if (!is_error(ret)) {
4839
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4840
                    goto efault;
4841
                host_to_target_old_sigset(p, &set);
4842
                unlock_user(p, arg1, sizeof(target_sigset_t));
4843
            }
4844
        }
4845
        break;
4846
#endif
4847
    case TARGET_NR_rt_sigpending:
4848
        {
4849
            sigset_t set;
4850
            ret = get_errno(sigpending(&set));
4851
            if (!is_error(ret)) {
4852
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4853
                    goto efault;
4854
                host_to_target_sigset(p, &set);
4855
                unlock_user(p, arg1, sizeof(target_sigset_t));
4856
            }
4857
        }
4858
        break;
4859
#ifdef TARGET_NR_sigsuspend
4860
    case TARGET_NR_sigsuspend:
4861
        {
4862
            sigset_t set;
4863
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4864
                goto efault;
4865
            target_to_host_old_sigset(&set, p);
4866
            unlock_user(p, arg1, 0);
4867
            ret = get_errno(sigsuspend(&set));
4868
        }
4869
        break;
4870
#endif
4871
    case TARGET_NR_rt_sigsuspend:
4872
        {
4873
            sigset_t set;
4874
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4875
                goto efault;
4876
            target_to_host_sigset(&set, p);
4877
            unlock_user(p, arg1, 0);
4878
            ret = get_errno(sigsuspend(&set));
4879
        }
4880
        break;
4881
    case TARGET_NR_rt_sigtimedwait:
4882
        {
4883
            sigset_t set;
4884
            struct timespec uts, *puts;
4885
            siginfo_t uinfo;
4886

    
4887
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4888
                goto efault;
4889
            target_to_host_sigset(&set, p);
4890
            unlock_user(p, arg1, 0);
4891
            if (arg3) {
4892
                puts = &uts;
4893
                target_to_host_timespec(puts, arg3);
4894
            } else {
4895
                puts = NULL;
4896
            }
4897
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4898
            if (!is_error(ret) && arg2) {
4899
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4900
                    goto efault;
4901
                host_to_target_siginfo(p, &uinfo);
4902
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4903
            }
4904
        }
4905
        break;
4906
    case TARGET_NR_rt_sigqueueinfo:
4907
        {
4908
            siginfo_t uinfo;
4909
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4910
                goto efault;
4911
            target_to_host_siginfo(&uinfo, p);
4912
            unlock_user(p, arg1, 0);
4913
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4914
        }
4915
        break;
4916
#ifdef TARGET_NR_sigreturn
4917
    case TARGET_NR_sigreturn:
4918
        /* NOTE: ret is eax, so not transcoding must be done */
4919
        ret = do_sigreturn(cpu_env);
4920
        break;
4921
#endif
4922
    case TARGET_NR_rt_sigreturn:
4923
        /* NOTE: ret is eax, so not transcoding must be done */
4924
        ret = do_rt_sigreturn(cpu_env);
4925
        break;
4926
    case TARGET_NR_sethostname:
4927
        if (!(p = lock_user_string(arg1)))
4928
            goto efault;
4929
        ret = get_errno(sethostname(p, arg2));
4930
        unlock_user(p, arg1, 0);
4931
        break;
4932
    case TARGET_NR_setrlimit:
4933
        {
4934
            /* XXX: convert resource ? */
4935
            int resource = arg1;
4936
            struct target_rlimit *target_rlim;
4937
            struct rlimit rlim;
4938
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4939
                goto efault;
4940
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4941
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4942
            unlock_user_struct(target_rlim, arg2, 0);
4943
            ret = get_errno(setrlimit(resource, &rlim));
4944
        }
4945
        break;
4946
    case TARGET_NR_getrlimit:
4947
        {
4948
            /* XXX: convert resource ? */
4949
            int resource = arg1;
4950
            struct target_rlimit *target_rlim;
4951
            struct rlimit rlim;
4952

    
4953
            ret = get_errno(getrlimit(resource, &rlim));
4954
            if (!is_error(ret)) {
4955
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4956
                    goto efault;
4957
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4958
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4959
                unlock_user_struct(target_rlim, arg2, 1);
4960
            }
4961
        }
4962
        break;
4963
    case TARGET_NR_getrusage:
4964
        {
4965
            struct rusage rusage;
4966
            ret = get_errno(getrusage(arg1, &rusage));
4967
            if (!is_error(ret)) {
4968
                host_to_target_rusage(arg2, &rusage);
4969
            }
4970
        }
4971
        break;
4972
    case TARGET_NR_gettimeofday:
4973
        {
4974
            struct timeval tv;
4975
            ret = get_errno(gettimeofday(&tv, NULL));
4976
            if (!is_error(ret)) {
4977
                if (copy_to_user_timeval(arg1, &tv))
4978
                    goto efault;
4979
            }
4980
        }
4981
        break;
4982
    case TARGET_NR_settimeofday:
4983
        {
4984
            struct timeval tv;
4985
            if (copy_from_user_timeval(&tv, arg1))
4986
                goto efault;
4987
            ret = get_errno(settimeofday(&tv, NULL));
4988
        }
4989
        break;
4990
#ifdef TARGET_NR_select
4991
    case TARGET_NR_select:
4992
        {
4993
            struct target_sel_arg_struct *sel;
4994
            abi_ulong inp, outp, exp, tvp;
4995
            long nsel;
4996

    
4997
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4998
                goto efault;
4999
            nsel = tswapl(sel->n);
5000
            inp = tswapl(sel->inp);
5001
            outp = tswapl(sel->outp);
5002
            exp = tswapl(sel->exp);
5003
            tvp = tswapl(sel->tvp);
5004
            unlock_user_struct(sel, arg1, 0);
5005
            ret = do_select(nsel, inp, outp, exp, tvp);
5006
        }
5007
        break;
5008
#endif
5009
    case TARGET_NR_symlink:
5010
        {
5011
            void *p2;
5012
            p = lock_user_string(arg1);
5013
            p2 = lock_user_string(arg2);
5014
            if (!p || !p2)
5015
                ret = -TARGET_EFAULT;
5016
            else
5017
                ret = get_errno(symlink(p, p2));
5018
            unlock_user(p2, arg2, 0);
5019
            unlock_user(p, arg1, 0);
5020
        }
5021
        break;
5022
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5023
    case TARGET_NR_symlinkat:
5024
        {
5025
            void *p2;
5026
            p  = lock_user_string(arg1);
5027
            p2 = lock_user_string(arg3);
5028
            if (!p || !p2)
5029
                ret = -TARGET_EFAULT;
5030
            else
5031
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5032
            unlock_user(p2, arg3, 0);
5033
            unlock_user(p, arg1, 0);
5034
        }
5035
        break;
5036
#endif
5037
#ifdef TARGET_NR_oldlstat
5038
    case TARGET_NR_oldlstat:
5039
        goto unimplemented;
5040
#endif
5041
    case TARGET_NR_readlink:
5042
        {
5043
            void *p2, *temp;
5044
            p = lock_user_string(arg1);
5045
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5046
            if (!p || !p2)
5047
                ret = -TARGET_EFAULT;
5048
            else {
5049
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5050
                    char real[PATH_MAX];
5051
                    temp = realpath(exec_path,real);
5052
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5053
                    snprintf((char *)p2, arg3, "%s", real);
5054
                    }
5055
                else
5056
                    ret = get_errno(readlink(path(p), p2, arg3));
5057
            }
5058
            unlock_user(p2, arg2, ret);
5059
            unlock_user(p, arg1, 0);
5060
        }
5061
        break;
5062
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5063
    case TARGET_NR_readlinkat:
5064
        {
5065
            void *p2;
5066
            p  = lock_user_string(arg2);
5067
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5068
            if (!p || !p2)
5069
                ret = -TARGET_EFAULT;
5070
            else
5071
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5072
            unlock_user(p2, arg3, ret);
5073
            unlock_user(p, arg2, 0);
5074
        }
5075
        break;
5076
#endif
5077
#ifdef TARGET_NR_uselib
5078
    case TARGET_NR_uselib:
5079
        goto unimplemented;
5080
#endif
5081
#ifdef TARGET_NR_swapon
5082
    case TARGET_NR_swapon:
5083
        if (!(p = lock_user_string(arg1)))
5084
            goto efault;
5085
        ret = get_errno(swapon(p, arg2));
5086
        unlock_user(p, arg1, 0);
5087
        break;
5088
#endif
5089
    case TARGET_NR_reboot:
5090
        goto unimplemented;
5091
#ifdef TARGET_NR_readdir
5092
    case TARGET_NR_readdir:
5093
        goto unimplemented;
5094
#endif
5095
#ifdef TARGET_NR_mmap
5096
    case TARGET_NR_mmap:
5097
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5098
        {
5099
            abi_ulong *v;
5100
            abi_ulong v1, v2, v3, v4, v5, v6;
5101
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5102
                goto efault;
5103
            v1 = tswapl(v[0]);
5104
            v2 = tswapl(v[1]);
5105
            v3 = tswapl(v[2]);
5106
            v4 = tswapl(v[3]);
5107
            v5 = tswapl(v[4]);
5108
            v6 = tswapl(v[5]);
5109
            unlock_user(v, arg1, 0);
5110
            ret = get_errno(target_mmap(v1, v2, v3,
5111
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5112
                                        v5, v6));
5113
        }
5114
#else
5115
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5116
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5117
                                    arg5,
5118
                                    arg6));
5119
#endif
5120
        break;
5121
#endif
5122
#ifdef TARGET_NR_mmap2
5123
    case TARGET_NR_mmap2:
5124
#ifndef MMAP_SHIFT
5125
#define MMAP_SHIFT 12
5126
#endif
5127
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5128
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5129
                                    arg5,
5130
                                    arg6 << MMAP_SHIFT));
5131
        break;
5132
#endif
5133
    case TARGET_NR_munmap:
5134
        ret = get_errno(target_munmap(arg1, arg2));
5135
        break;
5136
    case TARGET_NR_mprotect:
5137
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5138
        break;
5139
#ifdef TARGET_NR_mremap
5140
    case TARGET_NR_mremap:
5141
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5142
        break;
5143
#endif
5144
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5145
#ifdef TARGET_NR_msync
5146
    case TARGET_NR_msync:
5147
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5148
        break;
5149
#endif
5150
#ifdef TARGET_NR_mlock
5151
    case TARGET_NR_mlock:
5152
        ret = get_errno(mlock(g2h(arg1), arg2));
5153
        break;
5154
#endif
5155
#ifdef TARGET_NR_munlock
5156
    case TARGET_NR_munlock:
5157
        ret = get_errno(munlock(g2h(arg1), arg2));
5158
        break;
5159
#endif
5160
#ifdef TARGET_NR_mlockall
5161
    case TARGET_NR_mlockall:
5162
        ret = get_errno(mlockall(arg1));
5163
        break;
5164
#endif
5165
#ifdef TARGET_NR_munlockall
5166
    case TARGET_NR_munlockall:
5167
        ret = get_errno(munlockall());
5168
        break;
5169
#endif
5170
    case TARGET_NR_truncate:
5171
        if (!(p = lock_user_string(arg1)))
5172
            goto efault;
5173
        ret = get_errno(truncate(p, arg2));
5174
        unlock_user(p, arg1, 0);
5175
        break;
5176
    case TARGET_NR_ftruncate:
5177
        ret = get_errno(ftruncate(arg1, arg2));
5178
        break;
5179
    case TARGET_NR_fchmod:
5180
        ret = get_errno(fchmod(arg1, arg2));
5181
        break;
5182
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5183
    case TARGET_NR_fchmodat:
5184
        if (!(p = lock_user_string(arg2)))
5185
            goto efault;
5186
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5187
        unlock_user(p, arg2, 0);
5188
        break;
5189
#endif
5190
    case TARGET_NR_getpriority:
5191
        /* libc does special remapping of the return value of
5192
         * sys_getpriority() so it's just easiest to call
5193
         * sys_getpriority() directly rather than through libc. */
5194
        ret = sys_getpriority(arg1, arg2);
5195
        break;
5196
    case TARGET_NR_setpriority:
5197
        ret = get_errno(setpriority(arg1, arg2, arg3));
5198
        break;
5199
#ifdef TARGET_NR_profil
5200
    case TARGET_NR_profil:
5201
        goto unimplemented;
5202
#endif
5203
    case TARGET_NR_statfs:
5204
        if (!(p = lock_user_string(arg1)))
5205
            goto efault;
5206
        ret = get_errno(statfs(path(p), &stfs));
5207
        unlock_user(p, arg1, 0);
5208
    convert_statfs:
5209
        if (!is_error(ret)) {
5210
            struct target_statfs *target_stfs;
5211

    
5212
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5213
                goto efault;
5214
            __put_user(stfs.f_type, &target_stfs->f_type);
5215
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5216
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5217
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5218
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5219
            __put_user(stfs.f_files, &target_stfs->f_files);
5220
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5221
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5222
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5223
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5224
            unlock_user_struct(target_stfs, arg2, 1);
5225
        }
5226
        break;
5227
    case TARGET_NR_fstatfs:
5228
        ret = get_errno(fstatfs(arg1, &stfs));
5229
        goto convert_statfs;
5230
#ifdef TARGET_NR_statfs64
5231
    case TARGET_NR_statfs64:
5232
        if (!(p = lock_user_string(arg1)))
5233
            goto efault;
5234
        ret = get_errno(statfs(path(p), &stfs));
5235
        unlock_user(p, arg1, 0);
5236
    convert_statfs64:
5237
        if (!is_error(ret)) {
5238
            struct target_statfs64 *target_stfs;
5239

    
5240
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5241
                goto efault;
5242
            __put_user(stfs.f_type, &target_stfs->f_type);
5243
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5244
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5245
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5246
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5247
            __put_user(stfs.f_files, &target_stfs->f_files);
5248
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5249
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5250
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5251
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5252
            unlock_user_struct(target_stfs, arg3, 1);
5253
        }
5254
        break;
5255
    case TARGET_NR_fstatfs64:
5256
        ret = get_errno(fstatfs(arg1, &stfs));
5257
        goto convert_statfs64;
5258
#endif
5259
#ifdef TARGET_NR_ioperm
5260
    case TARGET_NR_ioperm:
5261
        goto unimplemented;
5262
#endif
5263
#ifdef TARGET_NR_socketcall
5264
    case TARGET_NR_socketcall:
5265
        ret = do_socketcall(arg1, arg2);
5266
        break;
5267
#endif
5268
#ifdef TARGET_NR_accept
5269
    case TARGET_NR_accept:
5270
        ret = do_accept(arg1, arg2, arg3);
5271
        break;
5272
#endif
5273
#ifdef TARGET_NR_bind
5274
    case TARGET_NR_bind:
5275
        ret = do_bind(arg1, arg2, arg3);
5276
        break;
5277
#endif
5278
#ifdef TARGET_NR_connect
5279
    case TARGET_NR_connect:
5280
        ret = do_connect(arg1, arg2, arg3);
5281
        break;
5282
#endif
5283
#ifdef TARGET_NR_getpeername
5284
    case TARGET_NR_getpeername:
5285
        ret = do_getpeername(arg1, arg2, arg3);
5286
        break;
5287
#endif
5288
#ifdef TARGET_NR_getsockname
5289
    case TARGET_NR_getsockname:
5290
        ret = do_getsockname(arg1, arg2, arg3);
5291
        break;
5292
#endif
5293
#ifdef TARGET_NR_getsockopt
5294
    case TARGET_NR_getsockopt:
5295
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5296
        break;
5297
#endif
5298
#ifdef TARGET_NR_listen
5299
    case TARGET_NR_listen:
5300
        ret = get_errno(listen(arg1, arg2));
5301
        break;
5302
#endif
5303
#ifdef TARGET_NR_recv
5304
    case TARGET_NR_recv:
5305
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5306
        break;
5307
#endif
5308
#ifdef TARGET_NR_recvfrom
5309
    case TARGET_NR_recvfrom:
5310
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5311
        break;
5312
#endif
5313
#ifdef TARGET_NR_recvmsg
5314
    case TARGET_NR_recvmsg:
5315
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5316
        break;
5317
#endif
5318
#ifdef TARGET_NR_send
5319
    case TARGET_NR_send:
5320
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5321
        break;
5322
#endif
5323
#ifdef TARGET_NR_sendmsg
5324
    case TARGET_NR_sendmsg:
5325
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5326
        break;
5327
#endif
5328
#ifdef TARGET_NR_sendto
5329
    case TARGET_NR_sendto:
5330
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5331
        break;
5332
#endif
5333
#ifdef TARGET_NR_shutdown
5334
    case TARGET_NR_shutdown:
5335
        ret = get_errno(shutdown(arg1, arg2));
5336
        break;
5337
#endif
5338
#ifdef TARGET_NR_socket
5339
    case TARGET_NR_socket:
5340
        ret = do_socket(arg1, arg2, arg3);
5341
        break;
5342
#endif
5343
#ifdef TARGET_NR_socketpair
5344
    case TARGET_NR_socketpair:
5345
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5346
        break;
5347
#endif
5348
#ifdef TARGET_NR_setsockopt
5349
    case TARGET_NR_setsockopt:
5350
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5351
        break;
5352
#endif
5353

    
5354
    case TARGET_NR_syslog:
5355
        if (!(p = lock_user_string(arg2)))
5356
            goto efault;
5357
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5358
        unlock_user(p, arg2, 0);
5359
        break;
5360

    
5361
    case TARGET_NR_setitimer:
5362
        {
5363
            struct itimerval value, ovalue, *pvalue;
5364

    
5365
            if (arg2) {
5366
                pvalue = &value;
5367
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5368
                    || copy_from_user_timeval(&pvalue->it_value,
5369
                                              arg2 + sizeof(struct target_timeval)))
5370
                    goto efault;
5371
            } else {
5372
                pvalue = NULL;
5373
            }
5374
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5375
            if (!is_error(ret) && arg3) {
5376
                if (copy_to_user_timeval(arg3,
5377
                                         &ovalue.it_interval)
5378
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5379
                                            &ovalue.it_value))
5380
                    goto efault;
5381
            }
5382
        }
5383
        break;
5384
    case TARGET_NR_getitimer:
5385
        {
5386
            struct itimerval value;
5387

    
5388
            ret = get_errno(getitimer(arg1, &value));
5389
            if (!is_error(ret) && arg2) {
5390
                if (copy_to_user_timeval(arg2,
5391
                                         &value.it_interval)
5392
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5393
                                            &value.it_value))
5394
                    goto efault;
5395
            }
5396
        }
5397
        break;
5398
    case TARGET_NR_stat:
5399
        if (!(p = lock_user_string(arg1)))
5400
            goto efault;
5401
        ret = get_errno(stat(path(p), &st));
5402
        unlock_user(p, arg1, 0);
5403
        goto do_stat;
5404
    case TARGET_NR_lstat:
5405
        if (!(p = lock_user_string(arg1)))
5406
            goto efault;
5407
        ret = get_errno(lstat(path(p), &st));
5408
        unlock_user(p, arg1, 0);
5409
        goto do_stat;
5410
    case TARGET_NR_fstat:
5411
        {
5412
            ret = get_errno(fstat(arg1, &st));
5413
        do_stat:
5414
            if (!is_error(ret)) {
5415
                struct target_stat *target_st;
5416

    
5417
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5418
                    goto efault;
5419
                __put_user(st.st_dev, &target_st->st_dev);
5420
                __put_user(st.st_ino, &target_st->st_ino);
5421
                __put_user(st.st_mode, &target_st->st_mode);
5422
                __put_user(st.st_uid, &target_st->st_uid);
5423
                __put_user(st.st_gid, &target_st->st_gid);
5424
                __put_user(st.st_nlink, &target_st->st_nlink);
5425
                __put_user(st.st_rdev, &target_st->st_rdev);
5426
                __put_user(st.st_size, &target_st->st_size);
5427
                __put_user(st.st_blksize, &target_st->st_blksize);
5428
                __put_user(st.st_blocks, &target_st->st_blocks);
5429
                __put_user(st.st_atime, &target_st->target_st_atime);
5430
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5431
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5432
                unlock_user_struct(target_st, arg2, 1);
5433
            }
5434
        }
5435
        break;
5436
#ifdef TARGET_NR_olduname
5437
    case TARGET_NR_olduname:
5438
        goto unimplemented;
5439
#endif
5440
#ifdef TARGET_NR_iopl
5441
    case TARGET_NR_iopl:
5442
        goto unimplemented;
5443
#endif
5444
    case TARGET_NR_vhangup:
5445
        ret = get_errno(vhangup());
5446
        break;
5447
#ifdef TARGET_NR_idle
5448
    case TARGET_NR_idle:
5449
        goto unimplemented;
5450
#endif
5451
#ifdef TARGET_NR_syscall
5452
    case TARGET_NR_syscall:
5453
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5454
            break;
5455
#endif
5456
    case TARGET_NR_wait4:
5457
        {
5458
            int status;
5459
            abi_long status_ptr = arg2;
5460
            struct rusage rusage, *rusage_ptr;
5461
            abi_ulong target_rusage = arg4;
5462
            if (target_rusage)
5463
                rusage_ptr = &rusage;
5464
            else
5465
                rusage_ptr = NULL;
5466
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5467
            if (!is_error(ret)) {
5468
                if (status_ptr) {
5469
                    status = host_to_target_waitstatus(status);
5470
                    if (put_user_s32(status, status_ptr))
5471
                        goto efault;
5472
                }
5473
                if (target_rusage)
5474
                    host_to_target_rusage(target_rusage, &rusage);
5475
            }
5476
        }
5477
        break;
5478
#ifdef TARGET_NR_swapoff
5479
    case TARGET_NR_swapoff:
5480
        if (!(p = lock_user_string(arg1)))
5481
            goto efault;
5482
        ret = get_errno(swapoff(p));
5483
        unlock_user(p, arg1, 0);
5484
        break;
5485
#endif
5486
    case TARGET_NR_sysinfo:
5487
        {
5488
            struct target_sysinfo *target_value;
5489
            struct sysinfo value;
5490
            ret = get_errno(sysinfo(&value));
5491
            if (!is_error(ret) && arg1)
5492
            {
5493
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5494
                    goto efault;
5495
                __put_user(value.uptime, &target_value->uptime);
5496
                __put_user(value.loads[0], &target_value->loads[0]);
5497
                __put_user(value.loads[1], &target_value->loads[1]);
5498
                __put_user(value.loads[2], &target_value->loads[2]);
5499
                __put_user(value.totalram, &target_value->totalram);
5500
                __put_user(value.freeram, &target_value->freeram);
5501
                __put_user(value.sharedram, &target_value->sharedram);
5502
                __put_user(value.bufferram, &target_value->bufferram);
5503
                __put_user(value.totalswap, &target_value->totalswap);
5504
                __put_user(value.freeswap, &target_value->freeswap);
5505
                __put_user(value.procs, &target_value->procs);
5506
                __put_user(value.totalhigh, &target_value->totalhigh);
5507
                __put_user(value.freehigh, &target_value->freehigh);
5508
                __put_user(value.mem_unit, &target_value->mem_unit);
5509
                unlock_user_struct(target_value, arg1, 1);
5510
            }
5511
        }
5512
        break;
5513
#ifdef TARGET_NR_ipc
5514
    case TARGET_NR_ipc:
5515
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5516
        break;
5517
#endif
5518
#ifdef TARGET_NR_semget
5519
    case TARGET_NR_semget:
5520
        ret = get_errno(semget(arg1, arg2, arg3));
5521
        break;
5522
#endif
5523
#ifdef TARGET_NR_semop
5524
    case TARGET_NR_semop:
5525
        ret = get_errno(do_semop(arg1, arg2, arg3));
5526
        break;
5527
#endif
5528
#ifdef TARGET_NR_semctl
5529
    case TARGET_NR_semctl:
5530
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5531
        break;
5532
#endif
5533
#ifdef TARGET_NR_msgctl
5534
    case TARGET_NR_msgctl:
5535
        ret = do_msgctl(arg1, arg2, arg3);
5536
        break;
5537
#endif
5538
#ifdef TARGET_NR_msgget
5539
    case TARGET_NR_msgget:
5540
        ret = get_errno(msgget(arg1, arg2));
5541
        break;
5542
#endif
5543
#ifdef TARGET_NR_msgrcv
5544
    case TARGET_NR_msgrcv:
5545
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5546
        break;
5547
#endif
5548
#ifdef TARGET_NR_msgsnd
5549
    case TARGET_NR_msgsnd:
5550
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5551
        break;
5552
#endif
5553
#ifdef TARGET_NR_shmget
5554
    case TARGET_NR_shmget:
5555
        ret = get_errno(shmget(arg1, arg2, arg3));
5556
        break;
5557
#endif
5558
#ifdef TARGET_NR_shmctl
5559
    case TARGET_NR_shmctl:
5560
        ret = do_shmctl(arg1, arg2, arg3);
5561
        break;
5562
#endif
5563
#ifdef TARGET_NR_shmat
5564
    case TARGET_NR_shmat:
5565
        ret = do_shmat(arg1, arg2, arg3);
5566
        break;
5567
#endif
5568
#ifdef TARGET_NR_shmdt
5569
    case TARGET_NR_shmdt:
5570
        ret = do_shmdt(arg1);
5571
        break;
5572
#endif
5573
    case TARGET_NR_fsync:
5574
        ret = get_errno(fsync(arg1));
5575
        break;
5576
    case TARGET_NR_clone:
5577
#if defined(TARGET_SH4)
5578
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5579
#elif defined(TARGET_CRIS)
5580
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5581
#else
5582
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5583
#endif
5584
        break;
5585
#ifdef __NR_exit_group
5586
        /* new thread calls */
5587
    case TARGET_NR_exit_group:
5588
#ifdef HAVE_GPROF
5589
        _mcleanup();
5590
#endif
5591
        gdb_exit(cpu_env, arg1);
5592
        ret = get_errno(exit_group(arg1));
5593
        break;
5594
#endif
5595
    case TARGET_NR_setdomainname:
5596
        if (!(p = lock_user_string(arg1)))
5597
            goto efault;
5598
        ret = get_errno(setdomainname(p, arg2));
5599
        unlock_user(p, arg1, 0);
5600
        break;
5601
    case TARGET_NR_uname:
5602
        /* no need to transcode because we use the linux syscall */
5603
        {
5604
            struct new_utsname * buf;
5605

    
5606
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5607
                goto efault;
5608
            ret = get_errno(sys_uname(buf));
5609
            if (!is_error(ret)) {
5610
                /* Overrite the native machine name with whatever is being
5611
                   emulated. */
5612
                strcpy (buf->machine, UNAME_MACHINE);
5613
                /* Allow the user to override the reported release.  */
5614
                if (qemu_uname_release && *qemu_uname_release)
5615
                  strcpy (buf->release, qemu_uname_release);
5616
            }
5617
            unlock_user_struct(buf, arg1, 1);
5618
        }
5619
        break;
5620
#ifdef TARGET_I386
5621
    case TARGET_NR_modify_ldt:
5622
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5623
        break;
5624
#if !defined(TARGET_X86_64)
5625
    case TARGET_NR_vm86old:
5626
        goto unimplemented;
5627
    case TARGET_NR_vm86:
5628
        ret = do_vm86(cpu_env, arg1, arg2);
5629
        break;
5630
#endif
5631
#endif
5632
    case TARGET_NR_adjtimex:
5633
        goto unimplemented;
5634
#ifdef TARGET_NR_create_module
5635
    case TARGET_NR_create_module:
5636
#endif
5637
    case TARGET_NR_init_module:
5638
    case TARGET_NR_delete_module:
5639
#ifdef TARGET_NR_get_kernel_syms
5640
    case TARGET_NR_get_kernel_syms:
5641
#endif
5642
        goto unimplemented;
5643
    case TARGET_NR_quotactl:
5644
        goto unimplemented;
5645
    case TARGET_NR_getpgid:
5646
        ret = get_errno(getpgid(arg1));
5647
        break;
5648
    case TARGET_NR_fchdir:
5649
        ret = get_errno(fchdir(arg1));
5650
        break;
5651
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5652
    case TARGET_NR_bdflush:
5653
        goto unimplemented;
5654
#endif
5655
#ifdef TARGET_NR_sysfs
5656
    case TARGET_NR_sysfs:
5657
        goto unimplemented;
5658
#endif
5659
    case TARGET_NR_personality:
5660
        ret = get_errno(personality(arg1));
5661
        break;
5662
#ifdef TARGET_NR_afs_syscall
5663
    case TARGET_NR_afs_syscall:
5664
        goto unimplemented;
5665
#endif
5666
#ifdef TARGET_NR__llseek /* Not on alpha */
5667
    case TARGET_NR__llseek:
5668
        {
5669
#if defined (__x86_64__)
5670
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5671
            if (put_user_s64(ret, arg4))
5672
                goto efault;
5673
#else
5674
            int64_t res;
5675
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5676
            if (put_user_s64(res, arg4))
5677
                goto efault;
5678
#endif
5679
        }
5680
        break;
5681
#endif
5682
    case TARGET_NR_getdents:
5683
#if TARGET_ABI_BITS != 32
5684
        goto unimplemented;
5685
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5686
        {
5687
            struct target_dirent *target_dirp;
5688
            struct linux_dirent *dirp;
5689
            abi_long count = arg3;
5690

    
5691
            dirp = malloc(count);
5692
            if (!dirp) {
5693
                ret = -TARGET_ENOMEM;
5694
                goto fail;
5695
            }
5696

    
5697
            ret = get_errno(sys_getdents(arg1, dirp, count));
5698
            if (!is_error(ret)) {
5699
                struct linux_dirent *de;
5700
                struct target_dirent *tde;
5701
                int len = ret;
5702
                int reclen, treclen;
5703
                int count1, tnamelen;
5704

    
5705
                count1 = 0;
5706
                de = dirp;
5707
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5708
                    goto efault;
5709
                tde = target_dirp;
5710
                while (len > 0) {
5711
                    reclen = de->d_reclen;
5712
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5713
                    tde->d_reclen = tswap16(treclen);
5714
                    tde->d_ino = tswapl(de->d_ino);
5715
                    tde->d_off = tswapl(de->d_off);
5716
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5717
                    if (tnamelen > 256)
5718
                        tnamelen = 256;
5719
                    /* XXX: may not be correct */
5720
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5721
                    de = (struct linux_dirent *)((char *)de + reclen);
5722
                    len -= reclen;
5723
                    tde = (struct target_dirent *)((char *)tde + treclen);
5724
                    count1 += treclen;
5725
                }
5726
                ret = count1;
5727
                unlock_user(target_dirp, arg2, ret);
5728
            }
5729
            free(dirp);
5730
        }
5731
#else
5732
        {
5733
            struct linux_dirent *dirp;
5734
            abi_long count = arg3;
5735

    
5736
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5737
                goto efault;
5738
            ret = get_errno(sys_getdents(arg1, dirp, count));
5739
            if (!is_error(ret)) {
5740
                struct linux_dirent *de;
5741
                int len = ret;
5742
                int reclen;
5743
                de = dirp;
5744
                while (len > 0) {
5745
                    reclen = de->d_reclen;
5746
                    if (reclen > len)
5747
                        break;
5748
                    de->d_reclen = tswap16(reclen);
5749
                    tswapls(&de->d_ino);
5750
                    tswapls(&de->d_off);
5751
                    de = (struct linux_dirent *)((char *)de + reclen);
5752
                    len -= reclen;
5753
                }
5754
            }
5755
            unlock_user(dirp, arg2, ret);
5756
        }
5757
#endif
5758
        break;
5759
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5760
    case TARGET_NR_getdents64:
5761
        {
5762
            struct linux_dirent64 *dirp;
5763
            abi_long count = arg3;
5764
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5765
                goto efault;
5766
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5767
            if (!is_error(ret)) {
5768
                struct linux_dirent64 *de;
5769
                int len = ret;
5770
                int reclen;
5771
                de = dirp;
5772
                while (len > 0) {
5773
                    reclen = de->d_reclen;
5774
                    if (reclen > len)
5775
                        break;
5776
                    de->d_reclen = tswap16(reclen);
5777
                    tswap64s((uint64_t *)&de->d_ino);
5778
                    tswap64s((uint64_t *)&de->d_off);
5779
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5780
                    len -= reclen;
5781
                }
5782
            }
5783
            unlock_user(dirp, arg2, ret);
5784
        }
5785
        break;
5786
#endif /* TARGET_NR_getdents64 */
5787
#ifdef TARGET_NR__newselect
5788
    case TARGET_NR__newselect:
5789
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5790
        break;
5791
#endif
5792
#ifdef TARGET_NR_poll
5793
    case TARGET_NR_poll:
5794
        {
5795
            struct target_pollfd *target_pfd;
5796
            unsigned int nfds = arg2;
5797
            int timeout = arg3;
5798
            struct pollfd *pfd;
5799
            unsigned int i;
5800

    
5801
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5802
            if (!target_pfd)
5803
                goto efault;
5804
            pfd = alloca(sizeof(struct pollfd) * nfds);
5805
            for(i = 0; i < nfds; i++) {
5806
                pfd[i].fd = tswap32(target_pfd[i].fd);
5807
                pfd[i].events = tswap16(target_pfd[i].events);
5808
            }
5809
            ret = get_errno(poll(pfd, nfds, timeout));
5810
            if (!is_error(ret)) {
5811
                for(i = 0; i < nfds; i++) {
5812
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5813
                }
5814
                ret += nfds * (sizeof(struct target_pollfd)
5815
                               - sizeof(struct pollfd));
5816
            }
5817
            unlock_user(target_pfd, arg1, ret);
5818
        }
5819
        break;
5820
#endif
5821
    case TARGET_NR_flock:
5822
        /* NOTE: the flock constant seems to be the same for every
5823
           Linux platform */
5824
        ret = get_errno(flock(arg1, arg2));
5825
        break;
5826
    case TARGET_NR_readv:
5827
        {
5828
            int count = arg3;
5829
            struct iovec *vec;
5830

    
5831
            vec = alloca(count * sizeof(struct iovec));
5832
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5833
                goto efault;
5834
            ret = get_errno(readv(arg1, vec, count));
5835
            unlock_iovec(vec, arg2, count, 1);
5836
        }
5837
        break;
5838
    case TARGET_NR_writev:
5839
        {
5840
            int count = arg3;
5841
            struct iovec *vec;
5842

    
5843
            vec = alloca(count * sizeof(struct iovec));
5844
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5845
                goto efault;
5846
            ret = get_errno(writev(arg1, vec, count));
5847
            unlock_iovec(vec, arg2, count, 0);
5848
        }
5849
        break;
5850
    case TARGET_NR_getsid:
5851
        ret = get_errno(getsid(arg1));
5852
        break;
5853
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5854
    case TARGET_NR_fdatasync:
5855
        ret = get_errno(fdatasync(arg1));
5856
        break;
5857
#endif
5858
    case TARGET_NR__sysctl:
5859
        /* We don't implement this, but ENOTDIR is always a safe
5860
           return value. */
5861
        ret = -TARGET_ENOTDIR;
5862
        break;
5863
    case TARGET_NR_sched_setparam:
5864
        {
5865
            struct sched_param *target_schp;
5866
            struct sched_param schp;
5867

    
5868
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5869
                goto efault;
5870
            schp.sched_priority = tswap32(target_schp->sched_priority);
5871
            unlock_user_struct(target_schp, arg2, 0);
5872
            ret = get_errno(sched_setparam(arg1, &schp));
5873
        }
5874
        break;
5875
    case TARGET_NR_sched_getparam:
5876
        {
5877
            struct sched_param *target_schp;
5878
            struct sched_param schp;
5879
            ret = get_errno(sched_getparam(arg1, &schp));
5880
            if (!is_error(ret)) {
5881
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5882
                    goto efault;
5883
                target_schp->sched_priority = tswap32(schp.sched_priority);
5884
                unlock_user_struct(target_schp, arg2, 1);
5885
            }
5886
        }
5887
        break;
5888
    case TARGET_NR_sched_setscheduler:
5889
        {
5890
            struct sched_param *target_schp;
5891
            struct sched_param schp;
5892
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5893
                goto efault;
5894
            schp.sched_priority = tswap32(target_schp->sched_priority);
5895
            unlock_user_struct(target_schp, arg3, 0);
5896
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5897
        }
5898
        break;
5899
    case TARGET_NR_sched_getscheduler:
5900
        ret = get_errno(sched_getscheduler(arg1));
5901
        break;
5902
    case TARGET_NR_sched_yield:
5903
        ret = get_errno(sched_yield());
5904
        break;
5905
    case TARGET_NR_sched_get_priority_max:
5906
        ret = get_errno(sched_get_priority_max(arg1));
5907
        break;
5908
    case TARGET_NR_sched_get_priority_min:
5909
        ret = get_errno(sched_get_priority_min(arg1));
5910
        break;
5911
    case TARGET_NR_sched_rr_get_interval:
5912
        {
5913
            struct timespec ts;
5914
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5915
            if (!is_error(ret)) {
5916
                host_to_target_timespec(arg2, &ts);
5917
            }
5918
        }
5919
        break;
5920
    case TARGET_NR_nanosleep:
5921
        {
5922
            struct timespec req, rem;
5923
            target_to_host_timespec(&req, arg1);
5924
            ret = get_errno(nanosleep(&req, &rem));
5925
            if (is_error(ret) && arg2) {
5926
                host_to_target_timespec(arg2, &rem);
5927
            }
5928
        }
5929
        break;
5930
#ifdef TARGET_NR_query_module
5931
    case TARGET_NR_query_module:
5932
        goto unimplemented;
5933
#endif
5934
#ifdef TARGET_NR_nfsservctl
5935
    case TARGET_NR_nfsservctl:
5936
        goto unimplemented;
5937
#endif
5938
    case TARGET_NR_prctl:
5939
        switch (arg1)
5940
            {
5941
            case PR_GET_PDEATHSIG:
5942
                {
5943
                    int deathsig;
5944
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5945
                    if (!is_error(ret) && arg2
5946
                        && put_user_ual(deathsig, arg2))
5947
                        goto efault;
5948
                }
5949
                break;
5950
            default:
5951
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5952
                break;
5953
            }
5954
        break;
5955
#ifdef TARGET_NR_arch_prctl
5956
    case TARGET_NR_arch_prctl:
5957
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5958
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5959
        break;
5960
#else
5961
        goto unimplemented;
5962
#endif
5963
#endif
5964
#ifdef TARGET_NR_pread
5965
    case TARGET_NR_pread:
5966
#ifdef TARGET_ARM
5967
        if (((CPUARMState *)cpu_env)->eabi)
5968
            arg4 = arg5;
5969
#endif
5970
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5971
            goto efault;
5972
        ret = get_errno(pread(arg1, p, arg3, arg4));
5973
        unlock_user(p, arg2, ret);
5974
        break;
5975
    case TARGET_NR_pwrite:
5976
#ifdef TARGET_ARM
5977
        if (((CPUARMState *)cpu_env)->eabi)
5978
            arg4 = arg5;
5979
#endif
5980
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5981
            goto efault;
5982
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5983
        unlock_user(p, arg2, 0);
5984
        break;
5985
#endif
5986
#ifdef TARGET_NR_pread64
5987
    case TARGET_NR_pread64:
5988
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5989
            goto efault;
5990
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5991
        unlock_user(p, arg2, ret);
5992
        break;
5993
    case TARGET_NR_pwrite64:
5994
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5995
            goto efault;
5996
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5997
        unlock_user(p, arg2, 0);
5998
        break;
5999
#endif
6000
    case TARGET_NR_getcwd:
6001
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6002
            goto efault;
6003
        ret = get_errno(sys_getcwd1(p, arg2));
6004
        unlock_user(p, arg1, ret);
6005
        break;
6006
    case TARGET_NR_capget:
6007
        goto unimplemented;
6008
    case TARGET_NR_capset:
6009
        goto unimplemented;
6010
    case TARGET_NR_sigaltstack:
6011
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6012
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
6013
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6014
        break;
6015
#else
6016
        goto unimplemented;
6017
#endif
6018
    case TARGET_NR_sendfile:
6019
        goto unimplemented;
6020
#ifdef TARGET_NR_getpmsg
6021
    case TARGET_NR_getpmsg:
6022
        goto unimplemented;
6023
#endif
6024
#ifdef TARGET_NR_putpmsg
6025
    case TARGET_NR_putpmsg:
6026
        goto unimplemented;
6027
#endif
6028
#ifdef TARGET_NR_vfork
6029
    case TARGET_NR_vfork:
6030
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6031
                        0, 0, 0, 0));
6032
        break;
6033
#endif
6034
#ifdef TARGET_NR_ugetrlimit
6035
    case TARGET_NR_ugetrlimit:
6036
    {
6037
        struct rlimit rlim;
6038
        ret = get_errno(getrlimit(arg1, &rlim));
6039
        if (!is_error(ret)) {
6040
            struct target_rlimit *target_rlim;
6041
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6042
                goto efault;
6043
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6044
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
6045
            unlock_user_struct(target_rlim, arg2, 1);
6046
        }
6047
        break;
6048
    }
6049
#endif
6050
#ifdef TARGET_NR_truncate64
6051
    case TARGET_NR_truncate64:
6052
        if (!(p = lock_user_string(arg1)))
6053
            goto efault;
6054
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6055
        unlock_user(p, arg1, 0);
6056
        break;
6057
#endif
6058
#ifdef TARGET_NR_ftruncate64
6059
    case TARGET_NR_ftruncate64:
6060
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6061
        break;
6062
#endif
6063
#ifdef TARGET_NR_stat64
6064
    case TARGET_NR_stat64:
6065
        if (!(p = lock_user_string(arg1)))
6066
            goto efault;
6067
        ret = get_errno(stat(path(p), &st));
6068
        unlock_user(p, arg1, 0);
6069
        if (!is_error(ret))
6070
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6071
        break;
6072
#endif
6073
#ifdef TARGET_NR_lstat64
6074
    case TARGET_NR_lstat64:
6075
        if (!(p = lock_user_string(arg1)))
6076
            goto efault;
6077
        ret = get_errno(lstat(path(p), &st));
6078
        unlock_user(p, arg1, 0);
6079
        if (!is_error(ret))
6080
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6081
        break;
6082
#endif
6083
#ifdef TARGET_NR_fstat64
6084
    case TARGET_NR_fstat64:
6085
        ret = get_errno(fstat(arg1, &st));
6086
        if (!is_error(ret))
6087
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6088
        break;
6089
#endif
6090
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6091
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6092
#ifdef TARGET_NR_fstatat64
6093
    case TARGET_NR_fstatat64:
6094
#endif
6095
#ifdef TARGET_NR_newfstatat
6096
    case TARGET_NR_newfstatat:
6097
#endif
6098
        if (!(p = lock_user_string(arg2)))
6099
            goto efault;
6100
#ifdef __NR_fstatat64
6101
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6102
#else
6103
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6104
#endif
6105
        if (!is_error(ret))
6106
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6107
        break;
6108
#endif
6109
#ifdef USE_UID16
6110
    case TARGET_NR_lchown:
6111
        if (!(p = lock_user_string(arg1)))
6112
            goto efault;
6113
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6114
        unlock_user(p, arg1, 0);
6115
        break;
6116
    case TARGET_NR_getuid:
6117
        ret = get_errno(high2lowuid(getuid()));
6118
        break;
6119
    case TARGET_NR_getgid:
6120
        ret = get_errno(high2lowgid(getgid()));
6121
        break;
6122
    case TARGET_NR_geteuid:
6123
        ret = get_errno(high2lowuid(geteuid()));
6124
        break;
6125
    case TARGET_NR_getegid:
6126
        ret = get_errno(high2lowgid(getegid()));
6127
        break;
6128
    case TARGET_NR_setreuid:
6129
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6130
        break;
6131
    case TARGET_NR_setregid:
6132
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6133
        break;
6134
    case TARGET_NR_getgroups:
6135
        {
6136
            int gidsetsize = arg1;
6137
            uint16_t *target_grouplist;
6138
            gid_t *grouplist;
6139
            int i;
6140

    
6141
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6142
            ret = get_errno(getgroups(gidsetsize, grouplist));
6143
            if (gidsetsize == 0)
6144
                break;
6145
            if (!is_error(ret)) {
6146
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6147
                if (!target_grouplist)
6148
                    goto efault;
6149
                for(i = 0;i < ret; i++)
6150
                    target_grouplist[i] = tswap16(grouplist[i]);
6151
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6152
            }
6153
        }
6154
        break;
6155
    case TARGET_NR_setgroups:
6156
        {
6157
            int gidsetsize = arg1;
6158
            uint16_t *target_grouplist;
6159
            gid_t *grouplist;
6160
            int i;
6161

    
6162
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6163
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6164
            if (!target_grouplist) {
6165
                ret = -TARGET_EFAULT;
6166
                goto fail;
6167
            }
6168
            for(i = 0;i < gidsetsize; i++)
6169
                grouplist[i] = tswap16(target_grouplist[i]);
6170
            unlock_user(target_grouplist, arg2, 0);
6171
            ret = get_errno(setgroups(gidsetsize, grouplist));
6172
        }
6173
        break;
6174
    case TARGET_NR_fchown:
6175
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6176
        break;
6177
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6178
    case TARGET_NR_fchownat:
6179
        if (!(p = lock_user_string(arg2))) 
6180
            goto efault;
6181
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6182
        unlock_user(p, arg2, 0);
6183
        break;
6184
#endif
6185
#ifdef TARGET_NR_setresuid
6186
    case TARGET_NR_setresuid:
6187
        ret = get_errno(setresuid(low2highuid(arg1),
6188
                                  low2highuid(arg2),
6189
                                  low2highuid(arg3)));
6190
        break;
6191
#endif
6192
#ifdef TARGET_NR_getresuid
6193
    case TARGET_NR_getresuid:
6194
        {
6195
            uid_t ruid, euid, suid;
6196
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6197
            if (!is_error(ret)) {
6198
                if (put_user_u16(high2lowuid(ruid), arg1)
6199
                    || put_user_u16(high2lowuid(euid), arg2)
6200
                    || put_user_u16(high2lowuid(suid), arg3))
6201
                    goto efault;
6202
            }
6203
        }
6204
        break;
6205
#endif
6206
#ifdef TARGET_NR_getresgid
6207
    case TARGET_NR_setresgid:
6208
        ret = get_errno(setresgid(low2highgid(arg1),
6209
                                  low2highgid(arg2),
6210
                                  low2highgid(arg3)));
6211
        break;
6212
#endif
6213
#ifdef TARGET_NR_getresgid
6214
    case TARGET_NR_getresgid:
6215
        {
6216
            gid_t rgid, egid, sgid;
6217
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6218
            if (!is_error(ret)) {
6219
                if (put_user_u16(high2lowgid(rgid), arg1)
6220
                    || put_user_u16(high2lowgid(egid), arg2)
6221
                    || put_user_u16(high2lowgid(sgid), arg3))
6222
                    goto efault;
6223
            }
6224
        }
6225
        break;
6226
#endif
6227
    case TARGET_NR_chown:
6228
        if (!(p = lock_user_string(arg1)))
6229
            goto efault;
6230
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6231
        unlock_user(p, arg1, 0);
6232
        break;
6233
    case TARGET_NR_setuid:
6234
        ret = get_errno(setuid(low2highuid(arg1)));
6235
        break;
6236
    case TARGET_NR_setgid:
6237
        ret = get_errno(setgid(low2highgid(arg1)));
6238
        break;
6239
    case TARGET_NR_setfsuid:
6240
        ret = get_errno(setfsuid(arg1));
6241
        break;
6242
    case TARGET_NR_setfsgid:
6243
        ret = get_errno(setfsgid(arg1));
6244
        break;
6245
#endif /* USE_UID16 */
6246

    
6247
#ifdef TARGET_NR_lchown32
6248
    case TARGET_NR_lchown32:
6249
        if (!(p = lock_user_string(arg1)))
6250
            goto efault;
6251
        ret = get_errno(lchown(p, arg2, arg3));
6252
        unlock_user(p, arg1, 0);
6253
        break;
6254
#endif
6255
#ifdef TARGET_NR_getuid32
6256
    case TARGET_NR_getuid32:
6257
        ret = get_errno(getuid());
6258
        break;
6259
#endif
6260

    
6261
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6262
   /* Alpha specific */
6263
    case TARGET_NR_getxuid:
6264
         {
6265
            uid_t euid;
6266
            euid=geteuid();
6267
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6268
         }
6269
        ret = get_errno(getuid());
6270
        break;
6271
#endif
6272
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6273
   /* Alpha specific */
6274
    case TARGET_NR_getxgid:
6275
         {
6276
            uid_t egid;
6277
            egid=getegid();
6278
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6279
         }
6280
        ret = get_errno(getgid());
6281
        break;
6282
#endif
6283

    
6284
#ifdef TARGET_NR_getgid32
6285
    case TARGET_NR_getgid32:
6286
        ret = get_errno(getgid());
6287
        break;
6288
#endif
6289
#ifdef TARGET_NR_geteuid32
6290
    case TARGET_NR_geteuid32:
6291
        ret = get_errno(geteuid());
6292
        break;
6293
#endif
6294
#ifdef TARGET_NR_getegid32
6295
    case TARGET_NR_getegid32:
6296
        ret = get_errno(getegid());
6297
        break;
6298
#endif
6299
#ifdef TARGET_NR_setreuid32
6300
    case TARGET_NR_setreuid32:
6301
        ret = get_errno(setreuid(arg1, arg2));
6302
        break;
6303
#endif
6304
#ifdef TARGET_NR_setregid32
6305
    case TARGET_NR_setregid32:
6306
        ret = get_errno(setregid(arg1, arg2));
6307
        break;
6308
#endif
6309
#ifdef TARGET_NR_getgroups32
6310
    case TARGET_NR_getgroups32:
6311
        {
6312
            int gidsetsize = arg1;
6313
            uint32_t *target_grouplist;
6314
            gid_t *grouplist;
6315
            int i;
6316

    
6317
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6318
            ret = get_errno(getgroups(gidsetsize, grouplist));
6319
            if (gidsetsize == 0)
6320
                break;
6321
            if (!is_error(ret)) {
6322
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6323
                if (!target_grouplist) {
6324
                    ret = -TARGET_EFAULT;
6325
                    goto fail;
6326
                }
6327
                for(i = 0;i < ret; i++)
6328
                    target_grouplist[i] = tswap32(grouplist[i]);
6329
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6330
            }
6331
        }
6332
        break;
6333
#endif
6334
#ifdef TARGET_NR_setgroups32
6335
    case TARGET_NR_setgroups32:
6336
        {
6337
            int gidsetsize = arg1;
6338
            uint32_t *target_grouplist;
6339
            gid_t *grouplist;
6340
            int i;
6341

    
6342
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6343
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6344
            if (!target_grouplist) {
6345
                ret = -TARGET_EFAULT;
6346
                goto fail;
6347
            }
6348
            for(i = 0;i < gidsetsize; i++)
6349
                grouplist[i] = tswap32(target_grouplist[i]);
6350
            unlock_user(target_grouplist, arg2, 0);
6351
            ret = get_errno(setgroups(gidsetsize, grouplist));
6352
        }
6353
        break;
6354
#endif
6355
#ifdef TARGET_NR_fchown32
6356
    case TARGET_NR_fchown32:
6357
        ret = get_errno(fchown(arg1, arg2, arg3));
6358
        break;
6359
#endif
6360
#ifdef TARGET_NR_setresuid32
6361
    case TARGET_NR_setresuid32:
6362
        ret = get_errno(setresuid(arg1, arg2, arg3));
6363
        break;
6364
#endif
6365
#ifdef TARGET_NR_getresuid32
6366
    case TARGET_NR_getresuid32:
6367
        {
6368
            uid_t ruid, euid, suid;
6369
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6370
            if (!is_error(ret)) {
6371
                if (put_user_u32(ruid, arg1)
6372
                    || put_user_u32(euid, arg2)
6373
                    || put_user_u32(suid, arg3))
6374
                    goto efault;
6375
            }
6376
        }
6377
        break;
6378
#endif
6379
#ifdef TARGET_NR_setresgid32
6380
    case TARGET_NR_setresgid32:
6381
        ret = get_errno(setresgid(arg1, arg2, arg3));
6382
        break;
6383
#endif
6384
#ifdef TARGET_NR_getresgid32
6385
    case TARGET_NR_getresgid32:
6386
        {
6387
            gid_t rgid, egid, sgid;
6388
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6389
            if (!is_error(ret)) {
6390
                if (put_user_u32(rgid, arg1)
6391
                    || put_user_u32(egid, arg2)
6392
                    || put_user_u32(sgid, arg3))
6393
                    goto efault;
6394
            }
6395
        }
6396
        break;
6397
#endif
6398
#ifdef TARGET_NR_chown32
6399
    case TARGET_NR_chown32:
6400
        if (!(p = lock_user_string(arg1)))
6401
            goto efault;
6402
        ret = get_errno(chown(p, arg2, arg3));
6403
        unlock_user(p, arg1, 0);
6404
        break;
6405
#endif
6406
#ifdef TARGET_NR_setuid32
6407
    case TARGET_NR_setuid32:
6408
        ret = get_errno(setuid(arg1));
6409
        break;
6410
#endif
6411
#ifdef TARGET_NR_setgid32
6412
    case TARGET_NR_setgid32:
6413
        ret = get_errno(setgid(arg1));
6414
        break;
6415
#endif
6416
#ifdef TARGET_NR_setfsuid32
6417
    case TARGET_NR_setfsuid32:
6418
        ret = get_errno(setfsuid(arg1));
6419
        break;
6420
#endif
6421
#ifdef TARGET_NR_setfsgid32
6422
    case TARGET_NR_setfsgid32:
6423
        ret = get_errno(setfsgid(arg1));
6424
        break;
6425
#endif
6426

    
6427
    case TARGET_NR_pivot_root:
6428
        goto unimplemented;
6429
#ifdef TARGET_NR_mincore
6430
    case TARGET_NR_mincore:
6431
        {
6432
            void *a;
6433
            ret = -TARGET_EFAULT;
6434
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6435
                goto efault;
6436
            if (!(p = lock_user_string(arg3)))
6437
                goto mincore_fail;
6438
            ret = get_errno(mincore(a, arg2, p));
6439
            unlock_user(p, arg3, ret);
6440
            mincore_fail:
6441
            unlock_user(a, arg1, 0);
6442
        }
6443
        break;
6444
#endif
6445
#ifdef TARGET_NR_arm_fadvise64_64
6446
    case TARGET_NR_arm_fadvise64_64:
6447
        {
6448
                /*
6449
                 * arm_fadvise64_64 looks like fadvise64_64 but
6450
                 * with different argument order
6451
                 */
6452
                abi_long temp;
6453
                temp = arg3;
6454
                arg3 = arg4;
6455
                arg4 = temp;
6456
        }
6457
#endif
6458
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6459
#ifdef TARGET_NR_fadvise64_64
6460
    case TARGET_NR_fadvise64_64:
6461
#endif
6462
        /* This is a hint, so ignoring and returning success is ok.  */
6463
        ret = get_errno(0);
6464
        break;
6465
#endif
6466
#ifdef TARGET_NR_madvise
6467
    case TARGET_NR_madvise:
6468
        /* A straight passthrough may not be safe because qemu sometimes
6469
           turns private flie-backed mappings into anonymous mappings.
6470
           This will break MADV_DONTNEED.
6471
           This is a hint, so ignoring and returning success is ok.  */
6472
        ret = get_errno(0);
6473
        break;
6474
#endif
6475
#if TARGET_ABI_BITS == 32
6476
    case TARGET_NR_fcntl64:
6477
    {
6478
        int cmd;
6479
        struct flock64 fl;
6480
        struct target_flock64 *target_fl;
6481
#ifdef TARGET_ARM
6482
        struct target_eabi_flock64 *target_efl;
6483
#endif
6484

    
6485
        switch(arg2){
6486
        case TARGET_F_GETLK64:
6487
            cmd = F_GETLK64;
6488
            break;
6489
        case TARGET_F_SETLK64:
6490
            cmd = F_SETLK64;
6491
            break;
6492
        case TARGET_F_SETLKW64:
6493
            cmd = F_SETLK64;
6494
            break;
6495
        default:
6496
            cmd = arg2;
6497
            break;
6498
        }
6499

    
6500
        switch(arg2) {
6501
        case TARGET_F_GETLK64:
6502
#ifdef TARGET_ARM
6503
            if (((CPUARMState *)cpu_env)->eabi) {
6504
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6505
                    goto efault;
6506
                fl.l_type = tswap16(target_efl->l_type);
6507
                fl.l_whence = tswap16(target_efl->l_whence);
6508
                fl.l_start = tswap64(target_efl->l_start);
6509
                fl.l_len = tswap64(target_efl->l_len);
6510
                fl.l_pid = tswapl(target_efl->l_pid);
6511
                unlock_user_struct(target_efl, arg3, 0);
6512
            } else
6513
#endif
6514
            {
6515
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6516
                    goto efault;
6517
                fl.l_type = tswap16(target_fl->l_type);
6518
                fl.l_whence = tswap16(target_fl->l_whence);
6519
                fl.l_start = tswap64(target_fl->l_start);
6520
                fl.l_len = tswap64(target_fl->l_len);
6521
                fl.l_pid = tswapl(target_fl->l_pid);
6522
                unlock_user_struct(target_fl, arg3, 0);
6523
            }
6524
            ret = get_errno(fcntl(arg1, cmd, &fl));
6525
            if (ret == 0) {
6526
#ifdef TARGET_ARM
6527
                if (((CPUARMState *)cpu_env)->eabi) {
6528
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6529
                        goto efault;
6530
                    target_efl->l_type = tswap16(fl.l_type);
6531
                    target_efl->l_whence = tswap16(fl.l_whence);
6532
                    target_efl->l_start = tswap64(fl.l_start);
6533
                    target_efl->l_len = tswap64(fl.l_len);
6534
                    target_efl->l_pid = tswapl(fl.l_pid);
6535
                    unlock_user_struct(target_efl, arg3, 1);
6536
                } else
6537
#endif
6538
                {
6539
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6540
                        goto efault;
6541
                    target_fl->l_type = tswap16(fl.l_type);
6542
                    target_fl->l_whence = tswap16(fl.l_whence);
6543
                    target_fl->l_start = tswap64(fl.l_start);
6544
                    target_fl->l_len = tswap64(fl.l_len);
6545
                    target_fl->l_pid = tswapl(fl.l_pid);
6546
                    unlock_user_struct(target_fl, arg3, 1);
6547
                }
6548
            }
6549
            break;
6550

    
6551
        case TARGET_F_SETLK64:
6552
        case TARGET_F_SETLKW64:
6553
#ifdef TARGET_ARM
6554
            if (((CPUARMState *)cpu_env)->eabi) {
6555
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6556
                    goto efault;
6557
                fl.l_type = tswap16(target_efl->l_type);
6558
                fl.l_whence = tswap16(target_efl->l_whence);
6559
                fl.l_start = tswap64(target_efl->l_start);
6560
                fl.l_len = tswap64(target_efl->l_len);
6561
                fl.l_pid = tswapl(target_efl->l_pid);
6562
                unlock_user_struct(target_efl, arg3, 0);
6563
            } else
6564
#endif
6565
            {
6566
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6567
                    goto efault;
6568
                fl.l_type = tswap16(target_fl->l_type);
6569
                fl.l_whence = tswap16(target_fl->l_whence);
6570
                fl.l_start = tswap64(target_fl->l_start);
6571
                fl.l_len = tswap64(target_fl->l_len);
6572
                fl.l_pid = tswapl(target_fl->l_pid);
6573
                unlock_user_struct(target_fl, arg3, 0);
6574
            }
6575
            ret = get_errno(fcntl(arg1, cmd, &fl));
6576
            break;
6577
        default:
6578
            ret = do_fcntl(arg1, cmd, arg3);
6579
            break;
6580
        }
6581
        break;
6582
    }
6583
#endif
6584
#ifdef TARGET_NR_cacheflush
6585
    case TARGET_NR_cacheflush:
6586
        /* self-modifying code is handled automatically, so nothing needed */
6587
        ret = 0;
6588
        break;
6589
#endif
6590
#ifdef TARGET_NR_security
6591
    case TARGET_NR_security:
6592
        goto unimplemented;
6593
#endif
6594
#ifdef TARGET_NR_getpagesize
6595
    case TARGET_NR_getpagesize:
6596
        ret = TARGET_PAGE_SIZE;
6597
        break;
6598
#endif
6599
    case TARGET_NR_gettid:
6600
        ret = get_errno(gettid());
6601
        break;
6602
#ifdef TARGET_NR_readahead
6603
    case TARGET_NR_readahead:
6604
#if TARGET_ABI_BITS == 32
6605
#ifdef TARGET_ARM
6606
        if (((CPUARMState *)cpu_env)->eabi)
6607
        {
6608
            arg2 = arg3;
6609
            arg3 = arg4;
6610
            arg4 = arg5;
6611
        }
6612
#endif
6613
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6614
#else
6615
        ret = get_errno(readahead(arg1, arg2, arg3));
6616
#endif
6617
        break;
6618
#endif
6619
#ifdef TARGET_NR_setxattr
6620
    case TARGET_NR_setxattr:
6621
    case TARGET_NR_lsetxattr:
6622
    case TARGET_NR_fsetxattr:
6623
    case TARGET_NR_getxattr:
6624
    case TARGET_NR_lgetxattr:
6625
    case TARGET_NR_fgetxattr:
6626
    case TARGET_NR_listxattr:
6627
    case TARGET_NR_llistxattr:
6628
    case TARGET_NR_flistxattr:
6629
    case TARGET_NR_removexattr:
6630
    case TARGET_NR_lremovexattr:
6631
    case TARGET_NR_fremovexattr:
6632
        ret = -TARGET_EOPNOTSUPP;
6633
        break;
6634
#endif
6635
#ifdef TARGET_NR_set_thread_area
6636
    case TARGET_NR_set_thread_area:
6637
#if defined(TARGET_MIPS)
6638
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6639
      ret = 0;
6640
      break;
6641
#elif defined(TARGET_CRIS)
6642
      if (arg1 & 0xff)
6643
          ret = -TARGET_EINVAL;
6644
      else {
6645
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6646
          ret = 0;
6647
      }
6648
      break;
6649
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6650
      ret = do_set_thread_area(cpu_env, arg1);
6651
      break;
6652
#else
6653
      goto unimplemented_nowarn;
6654
#endif
6655
#endif
6656
#ifdef TARGET_NR_get_thread_area
6657
    case TARGET_NR_get_thread_area:
6658
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6659
        ret = do_get_thread_area(cpu_env, arg1);
6660
#else
6661
        goto unimplemented_nowarn;
6662
#endif
6663
#endif
6664
#ifdef TARGET_NR_getdomainname
6665
    case TARGET_NR_getdomainname:
6666
        goto unimplemented_nowarn;
6667
#endif
6668

    
6669
#ifdef TARGET_NR_clock_gettime
6670
    case TARGET_NR_clock_gettime:
6671
    {
6672
        struct timespec ts;
6673
        ret = get_errno(clock_gettime(arg1, &ts));
6674
        if (!is_error(ret)) {
6675
            host_to_target_timespec(arg2, &ts);
6676
        }
6677
        break;
6678
    }
6679
#endif
6680
#ifdef TARGET_NR_clock_getres
6681
    case TARGET_NR_clock_getres:
6682
    {
6683
        struct timespec ts;
6684
        ret = get_errno(clock_getres(arg1, &ts));
6685
        if (!is_error(ret)) {
6686
            host_to_target_timespec(arg2, &ts);
6687
        }
6688
        break;
6689
    }
6690
#endif
6691
#ifdef TARGET_NR_clock_nanosleep
6692
    case TARGET_NR_clock_nanosleep:
6693
    {
6694
        struct timespec ts;
6695
        target_to_host_timespec(&ts, arg3);
6696
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6697
        if (arg4)
6698
            host_to_target_timespec(arg4, &ts);
6699
        break;
6700
    }
6701
#endif
6702

    
6703
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6704
    case TARGET_NR_set_tid_address:
6705
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6706
        break;
6707
#endif
6708

    
6709
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6710
    case TARGET_NR_tkill:
6711
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6712
        break;
6713
#endif
6714

    
6715
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6716
    case TARGET_NR_tgkill:
6717
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6718
                        target_to_host_signal(arg3)));
6719
        break;
6720
#endif
6721

    
6722
#ifdef TARGET_NR_set_robust_list
6723
    case TARGET_NR_set_robust_list:
6724
        goto unimplemented_nowarn;
6725
#endif
6726

    
6727
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6728
    case TARGET_NR_utimensat:
6729
        {
6730
            struct timespec *tsp, ts[2];
6731
            if (!arg3) {
6732
                tsp = NULL;
6733
            } else {
6734
                target_to_host_timespec(ts, arg3);
6735
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6736
                tsp = ts;
6737
            }
6738
            if (!arg2)
6739
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6740
            else {
6741
                if (!(p = lock_user_string(arg2))) {
6742
                    ret = -TARGET_EFAULT;
6743
                    goto fail;
6744
                }
6745
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6746
                unlock_user(p, arg2, 0);
6747
            }
6748
        }
6749
        break;
6750
#endif
6751
#if defined(USE_NPTL)
6752
    case TARGET_NR_futex:
6753
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6754
        break;
6755
#endif
6756
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6757
    case TARGET_NR_inotify_init:
6758
        ret = get_errno(sys_inotify_init());
6759
        break;
6760
#endif
6761
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6762
    case TARGET_NR_inotify_add_watch:
6763
        p = lock_user_string(arg2);
6764
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6765
        unlock_user(p, arg2, 0);
6766
        break;
6767
#endif
6768
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6769
    case TARGET_NR_inotify_rm_watch:
6770
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6771
        break;
6772
#endif
6773

    
6774
#ifdef TARGET_NR_mq_open
6775
    case TARGET_NR_mq_open:
6776
        {
6777
            struct mq_attr posix_mq_attr;
6778

    
6779
            p = lock_user_string(arg1 - 1);
6780
            if (arg4 != 0)
6781
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6782
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6783
            unlock_user (p, arg1, 0);
6784
        }
6785
        break;
6786

    
6787
    case TARGET_NR_mq_unlink:
6788
        p = lock_user_string(arg1 - 1);
6789
        ret = get_errno(mq_unlink(p));
6790
        unlock_user (p, arg1, 0);
6791
        break;
6792

    
6793
    case TARGET_NR_mq_timedsend:
6794
        {
6795
            struct timespec ts;
6796

    
6797
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6798
            if (arg5 != 0) {
6799
                target_to_host_timespec(&ts, arg5);
6800
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6801
                host_to_target_timespec(arg5, &ts);
6802
            }
6803
            else
6804
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6805
            unlock_user (p, arg2, arg3);
6806
        }
6807
        break;
6808

    
6809
    case TARGET_NR_mq_timedreceive:
6810
        {
6811
            struct timespec ts;
6812
            unsigned int prio;
6813

    
6814
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6815
            if (arg5 != 0) {
6816
                target_to_host_timespec(&ts, arg5);
6817
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6818
                host_to_target_timespec(arg5, &ts);
6819
            }
6820
            else
6821
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6822
            unlock_user (p, arg2, arg3);
6823
            if (arg4 != 0)
6824
                put_user_u32(prio, arg4);
6825
        }
6826
        break;
6827

    
6828
    /* Not implemented for now... */
6829
/*     case TARGET_NR_mq_notify: */
6830
/*         break; */
6831

    
6832
    case TARGET_NR_mq_getsetattr:
6833
        {
6834
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6835
            ret = 0;
6836
            if (arg3 != 0) {
6837
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6838
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6839
            }
6840
            if (arg2 != 0) {
6841
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6842
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6843
            }
6844

    
6845
        }
6846
        break;
6847
#endif
6848

    
6849
    default:
6850
    unimplemented:
6851
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6852
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6853
    unimplemented_nowarn:
6854
#endif
6855
        ret = -TARGET_ENOSYS;
6856
        break;
6857
    }
6858
fail:
6859
#ifdef DEBUG
6860
    gemu_log(" = %ld\n", ret);
6861
#endif
6862
    if(do_strace)
6863
        print_syscall_ret(num, ret);
6864
    return ret;
6865
efault:
6866
    ret = -TARGET_EFAULT;
6867
    goto fail;
6868
}