Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 3ce34dfb

History | View | Annotate | Download (211.6 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 abi_long do_pipe2(int host_pipe[], int flags)
948
{
949
#ifdef CONFIG_PIPE2
950
    return pipe2(host_pipe, flags);
951
#else
952
    return -ENOSYS;
953
#endif
954
}
955

    
956
static abi_long do_pipe(void *cpu_env, int pipedes, int flags)
957
{
958
    int host_pipe[2];
959
    abi_long ret;
960
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
961

    
962
    if (is_error(ret))
963
        return get_errno(ret);
964
#if defined(TARGET_MIPS)
965
    ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
966
    ret = host_pipe[0];
967
#elif defined(TARGET_SH4)
968
    ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
969
    ret = host_pipe[0];
970
#else
971
    if (put_user_s32(host_pipe[0], pipedes)
972
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
973
        return -TARGET_EFAULT;
974
#endif
975
    return get_errno(ret);
976
}
977

    
978
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
979
                                              abi_ulong target_addr,
980
                                              socklen_t len)
981
{
982
    struct target_ip_mreqn *target_smreqn;
983

    
984
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
985
    if (!target_smreqn)
986
        return -TARGET_EFAULT;
987
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
988
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
989
    if (len == sizeof(struct target_ip_mreqn))
990
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
991
    unlock_user(target_smreqn, target_addr, 0);
992

    
993
    return 0;
994
}
995

    
996
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
997
                                               abi_ulong target_addr,
998
                                               socklen_t len)
999
{
1000
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1001
    sa_family_t sa_family;
1002
    struct target_sockaddr *target_saddr;
1003

    
1004
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1005
    if (!target_saddr)
1006
        return -TARGET_EFAULT;
1007

    
1008
    sa_family = tswap16(target_saddr->sa_family);
1009

    
1010
    /* Oops. The caller might send a incomplete sun_path; sun_path
1011
     * must be terminated by \0 (see the manual page), but
1012
     * unfortunately it is quite common to specify sockaddr_un
1013
     * length as "strlen(x->sun_path)" while it should be
1014
     * "strlen(...) + 1". We'll fix that here if needed.
1015
     * Linux kernel has a similar feature.
1016
     */
1017

    
1018
    if (sa_family == AF_UNIX) {
1019
        if (len < unix_maxlen && len > 0) {
1020
            char *cp = (char*)target_saddr;
1021

    
1022
            if ( cp[len-1] && !cp[len] )
1023
                len++;
1024
        }
1025
        if (len > unix_maxlen)
1026
            len = unix_maxlen;
1027
    }
1028

    
1029
    memcpy(addr, target_saddr, len);
1030
    addr->sa_family = sa_family;
1031
    unlock_user(target_saddr, target_addr, 0);
1032

    
1033
    return 0;
1034
}
1035

    
1036
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1037
                                               struct sockaddr *addr,
1038
                                               socklen_t len)
1039
{
1040
    struct target_sockaddr *target_saddr;
1041

    
1042
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1043
    if (!target_saddr)
1044
        return -TARGET_EFAULT;
1045
    memcpy(target_saddr, addr, len);
1046
    target_saddr->sa_family = tswap16(addr->sa_family);
1047
    unlock_user(target_saddr, target_addr, len);
1048

    
1049
    return 0;
1050
}
1051

    
1052
/* ??? Should this also swap msgh->name?  */
1053
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1054
                                           struct target_msghdr *target_msgh)
1055
{
1056
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1057
    abi_long msg_controllen;
1058
    abi_ulong target_cmsg_addr;
1059
    struct target_cmsghdr *target_cmsg;
1060
    socklen_t space = 0;
1061
    
1062
    msg_controllen = tswapl(target_msgh->msg_controllen);
1063
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1064
        goto the_end;
1065
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1066
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1067
    if (!target_cmsg)
1068
        return -TARGET_EFAULT;
1069

    
1070
    while (cmsg && target_cmsg) {
1071
        void *data = CMSG_DATA(cmsg);
1072
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1073

    
1074
        int len = tswapl(target_cmsg->cmsg_len)
1075
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1076

    
1077
        space += CMSG_SPACE(len);
1078
        if (space > msgh->msg_controllen) {
1079
            space -= CMSG_SPACE(len);
1080
            gemu_log("Host cmsg overflow\n");
1081
            break;
1082
        }
1083

    
1084
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1085
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1086
        cmsg->cmsg_len = CMSG_LEN(len);
1087

    
1088
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1089
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1090
            memcpy(data, target_data, len);
1091
        } else {
1092
            int *fd = (int *)data;
1093
            int *target_fd = (int *)target_data;
1094
            int i, numfds = len / sizeof(int);
1095

    
1096
            for (i = 0; i < numfds; i++)
1097
                fd[i] = tswap32(target_fd[i]);
1098
        }
1099

    
1100
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1101
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1102
    }
1103
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1104
 the_end:
1105
    msgh->msg_controllen = space;
1106
    return 0;
1107
}
1108

    
1109
/* ??? Should this also swap msgh->name?  */
1110
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1111
                                           struct msghdr *msgh)
1112
{
1113
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1114
    abi_long msg_controllen;
1115
    abi_ulong target_cmsg_addr;
1116
    struct target_cmsghdr *target_cmsg;
1117
    socklen_t space = 0;
1118

    
1119
    msg_controllen = tswapl(target_msgh->msg_controllen);
1120
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1121
        goto the_end;
1122
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1123
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1124
    if (!target_cmsg)
1125
        return -TARGET_EFAULT;
1126

    
1127
    while (cmsg && target_cmsg) {
1128
        void *data = CMSG_DATA(cmsg);
1129
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1130

    
1131
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1132

    
1133
        space += TARGET_CMSG_SPACE(len);
1134
        if (space > msg_controllen) {
1135
            space -= TARGET_CMSG_SPACE(len);
1136
            gemu_log("Target cmsg overflow\n");
1137
            break;
1138
        }
1139

    
1140
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1141
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1142
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1143

    
1144
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1145
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1146
            memcpy(target_data, data, len);
1147
        } else {
1148
            int *fd = (int *)data;
1149
            int *target_fd = (int *)target_data;
1150
            int i, numfds = len / sizeof(int);
1151

    
1152
            for (i = 0; i < numfds; i++)
1153
                target_fd[i] = tswap32(fd[i]);
1154
        }
1155

    
1156
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1157
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1158
    }
1159
    unlock_user(target_cmsg, target_cmsg_addr, space);
1160
 the_end:
1161
    target_msgh->msg_controllen = tswapl(space);
1162
    return 0;
1163
}
1164

    
1165
/* do_setsockopt() Must return target values and target errnos. */
1166
static abi_long do_setsockopt(int sockfd, int level, int optname,
1167
                              abi_ulong optval_addr, socklen_t optlen)
1168
{
1169
    abi_long ret;
1170
    int val;
1171
    struct ip_mreqn *ip_mreq;
1172
    struct ip_mreq_source *ip_mreq_source;
1173

    
1174
    switch(level) {
1175
    case SOL_TCP:
1176
        /* TCP options all take an 'int' value.  */
1177
        if (optlen < sizeof(uint32_t))
1178
            return -TARGET_EINVAL;
1179

    
1180
        if (get_user_u32(val, optval_addr))
1181
            return -TARGET_EFAULT;
1182
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1183
        break;
1184
    case SOL_IP:
1185
        switch(optname) {
1186
        case IP_TOS:
1187
        case IP_TTL:
1188
        case IP_HDRINCL:
1189
        case IP_ROUTER_ALERT:
1190
        case IP_RECVOPTS:
1191
        case IP_RETOPTS:
1192
        case IP_PKTINFO:
1193
        case IP_MTU_DISCOVER:
1194
        case IP_RECVERR:
1195
        case IP_RECVTOS:
1196
#ifdef IP_FREEBIND
1197
        case IP_FREEBIND:
1198
#endif
1199
        case IP_MULTICAST_TTL:
1200
        case IP_MULTICAST_LOOP:
1201
            val = 0;
1202
            if (optlen >= sizeof(uint32_t)) {
1203
                if (get_user_u32(val, optval_addr))
1204
                    return -TARGET_EFAULT;
1205
            } else if (optlen >= 1) {
1206
                if (get_user_u8(val, optval_addr))
1207
                    return -TARGET_EFAULT;
1208
            }
1209
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1210
            break;
1211
        case IP_ADD_MEMBERSHIP:
1212
        case IP_DROP_MEMBERSHIP:
1213
            if (optlen < sizeof (struct target_ip_mreq) ||
1214
                optlen > sizeof (struct target_ip_mreqn))
1215
                return -TARGET_EINVAL;
1216

    
1217
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1218
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1219
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1220
            break;
1221

    
1222
        case IP_BLOCK_SOURCE:
1223
        case IP_UNBLOCK_SOURCE:
1224
        case IP_ADD_SOURCE_MEMBERSHIP:
1225
        case IP_DROP_SOURCE_MEMBERSHIP:
1226
            if (optlen != sizeof (struct target_ip_mreq_source))
1227
                return -TARGET_EINVAL;
1228

    
1229
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1230
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1231
            unlock_user (ip_mreq_source, optval_addr, 0);
1232
            break;
1233

    
1234
        default:
1235
            goto unimplemented;
1236
        }
1237
        break;
1238
    case TARGET_SOL_SOCKET:
1239
        switch (optname) {
1240
            /* Options with 'int' argument.  */
1241
        case TARGET_SO_DEBUG:
1242
                optname = SO_DEBUG;
1243
                break;
1244
        case TARGET_SO_REUSEADDR:
1245
                optname = SO_REUSEADDR;
1246
                break;
1247
        case TARGET_SO_TYPE:
1248
                optname = SO_TYPE;
1249
                break;
1250
        case TARGET_SO_ERROR:
1251
                optname = SO_ERROR;
1252
                break;
1253
        case TARGET_SO_DONTROUTE:
1254
                optname = SO_DONTROUTE;
1255
                break;
1256
        case TARGET_SO_BROADCAST:
1257
                optname = SO_BROADCAST;
1258
                break;
1259
        case TARGET_SO_SNDBUF:
1260
                optname = SO_SNDBUF;
1261
                break;
1262
        case TARGET_SO_RCVBUF:
1263
                optname = SO_RCVBUF;
1264
                break;
1265
        case TARGET_SO_KEEPALIVE:
1266
                optname = SO_KEEPALIVE;
1267
                break;
1268
        case TARGET_SO_OOBINLINE:
1269
                optname = SO_OOBINLINE;
1270
                break;
1271
        case TARGET_SO_NO_CHECK:
1272
                optname = SO_NO_CHECK;
1273
                break;
1274
        case TARGET_SO_PRIORITY:
1275
                optname = SO_PRIORITY;
1276
                break;
1277
#ifdef SO_BSDCOMPAT
1278
        case TARGET_SO_BSDCOMPAT:
1279
                optname = SO_BSDCOMPAT;
1280
                break;
1281
#endif
1282
        case TARGET_SO_PASSCRED:
1283
                optname = SO_PASSCRED;
1284
                break;
1285
        case TARGET_SO_TIMESTAMP:
1286
                optname = SO_TIMESTAMP;
1287
                break;
1288
        case TARGET_SO_RCVLOWAT:
1289
                optname = SO_RCVLOWAT;
1290
                break;
1291
        case TARGET_SO_RCVTIMEO:
1292
                optname = SO_RCVTIMEO;
1293
                break;
1294
        case TARGET_SO_SNDTIMEO:
1295
                optname = SO_SNDTIMEO;
1296
                break;
1297
            break;
1298
        default:
1299
            goto unimplemented;
1300
        }
1301
        if (optlen < sizeof(uint32_t))
1302
            return -TARGET_EINVAL;
1303

    
1304
        if (get_user_u32(val, optval_addr))
1305
            return -TARGET_EFAULT;
1306
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1307
        break;
1308
    default:
1309
    unimplemented:
1310
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1311
        ret = -TARGET_ENOPROTOOPT;
1312
    }
1313
    return ret;
1314
}
1315

    
1316
/* do_getsockopt() Must return target values and target errnos. */
1317
static abi_long do_getsockopt(int sockfd, int level, int optname,
1318
                              abi_ulong optval_addr, abi_ulong optlen)
1319
{
1320
    abi_long ret;
1321
    int len, val;
1322
    socklen_t lv;
1323

    
1324
    switch(level) {
1325
    case TARGET_SOL_SOCKET:
1326
            level = SOL_SOCKET;
1327
        switch (optname) {
1328
        case TARGET_SO_LINGER:
1329
        case TARGET_SO_RCVTIMEO:
1330
        case TARGET_SO_SNDTIMEO:
1331
        case TARGET_SO_PEERCRED:
1332
        case TARGET_SO_PEERNAME:
1333
            /* These don't just return a single integer */
1334
            goto unimplemented;
1335
        default:
1336
            goto int_case;
1337
        }
1338
        break;
1339
    case SOL_TCP:
1340
        /* TCP options all take an 'int' value.  */
1341
    int_case:
1342
        if (get_user_u32(len, optlen))
1343
            return -TARGET_EFAULT;
1344
        if (len < 0)
1345
            return -TARGET_EINVAL;
1346
        lv = sizeof(int);
1347
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1348
        if (ret < 0)
1349
            return ret;
1350
        val = tswap32(val);
1351
        if (len > lv)
1352
            len = lv;
1353
        if (len == 4) {
1354
            if (put_user_u32(val, optval_addr))
1355
                return -TARGET_EFAULT;
1356
        } else {
1357
            if (put_user_u8(val, optval_addr))
1358
                return -TARGET_EFAULT;
1359
        }
1360
        if (put_user_u32(len, optlen))
1361
            return -TARGET_EFAULT;
1362
        break;
1363
    case SOL_IP:
1364
        switch(optname) {
1365
        case IP_TOS:
1366
        case IP_TTL:
1367
        case IP_HDRINCL:
1368
        case IP_ROUTER_ALERT:
1369
        case IP_RECVOPTS:
1370
        case IP_RETOPTS:
1371
        case IP_PKTINFO:
1372
        case IP_MTU_DISCOVER:
1373
        case IP_RECVERR:
1374
        case IP_RECVTOS:
1375
#ifdef IP_FREEBIND
1376
        case IP_FREEBIND:
1377
#endif
1378
        case IP_MULTICAST_TTL:
1379
        case IP_MULTICAST_LOOP:
1380
            if (get_user_u32(len, optlen))
1381
                return -TARGET_EFAULT;
1382
            if (len < 0)
1383
                return -TARGET_EINVAL;
1384
            lv = sizeof(int);
1385
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1386
            if (ret < 0)
1387
                return ret;
1388
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1389
                len = 1;
1390
                if (put_user_u32(len, optlen)
1391
                    || put_user_u8(val, optval_addr))
1392
                    return -TARGET_EFAULT;
1393
            } else {
1394
                if (len > sizeof(int))
1395
                    len = sizeof(int);
1396
                if (put_user_u32(len, optlen)
1397
                    || put_user_u32(val, optval_addr))
1398
                    return -TARGET_EFAULT;
1399
            }
1400
            break;
1401
        default:
1402
            ret = -TARGET_ENOPROTOOPT;
1403
            break;
1404
        }
1405
        break;
1406
    default:
1407
    unimplemented:
1408
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1409
                 level, optname);
1410
        ret = -TARGET_EOPNOTSUPP;
1411
        break;
1412
    }
1413
    return ret;
1414
}
1415

    
1416
/* FIXME
1417
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1418
 * other lock functions have a return code of 0 for failure.
1419
 */
1420
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1421
                           int count, int copy)
1422
{
1423
    struct target_iovec *target_vec;
1424
    abi_ulong base;
1425
    int i;
1426

    
1427
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1428
    if (!target_vec)
1429
        return -TARGET_EFAULT;
1430
    for(i = 0;i < count; i++) {
1431
        base = tswapl(target_vec[i].iov_base);
1432
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1433
        if (vec[i].iov_len != 0) {
1434
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1435
            /* Don't check lock_user return value. We must call writev even
1436
               if a element has invalid base address. */
1437
        } else {
1438
            /* zero length pointer is ignored */
1439
            vec[i].iov_base = NULL;
1440
        }
1441
    }
1442
    unlock_user (target_vec, target_addr, 0);
1443
    return 0;
1444
}
1445

    
1446
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1447
                             int count, int copy)
1448
{
1449
    struct target_iovec *target_vec;
1450
    abi_ulong base;
1451
    int i;
1452

    
1453
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1454
    if (!target_vec)
1455
        return -TARGET_EFAULT;
1456
    for(i = 0;i < count; i++) {
1457
        if (target_vec[i].iov_base) {
1458
            base = tswapl(target_vec[i].iov_base);
1459
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1460
        }
1461
    }
1462
    unlock_user (target_vec, target_addr, 0);
1463

    
1464
    return 0;
1465
}
1466

    
1467
/* do_socket() Must return target values and target errnos. */
1468
static abi_long do_socket(int domain, int type, int protocol)
1469
{
1470
#if defined(TARGET_MIPS)
1471
    switch(type) {
1472
    case TARGET_SOCK_DGRAM:
1473
        type = SOCK_DGRAM;
1474
        break;
1475
    case TARGET_SOCK_STREAM:
1476
        type = SOCK_STREAM;
1477
        break;
1478
    case TARGET_SOCK_RAW:
1479
        type = SOCK_RAW;
1480
        break;
1481
    case TARGET_SOCK_RDM:
1482
        type = SOCK_RDM;
1483
        break;
1484
    case TARGET_SOCK_SEQPACKET:
1485
        type = SOCK_SEQPACKET;
1486
        break;
1487
    case TARGET_SOCK_PACKET:
1488
        type = SOCK_PACKET;
1489
        break;
1490
    }
1491
#endif
1492
    if (domain == PF_NETLINK)
1493
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1494
    return get_errno(socket(domain, type, protocol));
1495
}
1496

    
1497
/* do_bind() Must return target values and target errnos. */
1498
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1499
                        socklen_t addrlen)
1500
{
1501
    void *addr;
1502

    
1503
    if (addrlen < 0)
1504
        return -TARGET_EINVAL;
1505

    
1506
    addr = alloca(addrlen+1);
1507

    
1508
    target_to_host_sockaddr(addr, target_addr, addrlen);
1509
    return get_errno(bind(sockfd, addr, addrlen));
1510
}
1511

    
1512
/* do_connect() Must return target values and target errnos. */
1513
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1514
                           socklen_t addrlen)
1515
{
1516
    void *addr;
1517

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

    
1521
    addr = alloca(addrlen);
1522

    
1523
    target_to_host_sockaddr(addr, target_addr, addrlen);
1524
    return get_errno(connect(sockfd, addr, addrlen));
1525
}
1526

    
1527
/* do_sendrecvmsg() Must return target values and target errnos. */
1528
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1529
                               int flags, int send)
1530
{
1531
    abi_long ret, len;
1532
    struct target_msghdr *msgp;
1533
    struct msghdr msg;
1534
    int count;
1535
    struct iovec *vec;
1536
    abi_ulong target_vec;
1537

    
1538
    /* FIXME */
1539
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1540
                          msgp,
1541
                          target_msg,
1542
                          send ? 1 : 0))
1543
        return -TARGET_EFAULT;
1544
    if (msgp->msg_name) {
1545
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1546
        msg.msg_name = alloca(msg.msg_namelen);
1547
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1548
                                msg.msg_namelen);
1549
    } else {
1550
        msg.msg_name = NULL;
1551
        msg.msg_namelen = 0;
1552
    }
1553
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1554
    msg.msg_control = alloca(msg.msg_controllen);
1555
    msg.msg_flags = tswap32(msgp->msg_flags);
1556

    
1557
    count = tswapl(msgp->msg_iovlen);
1558
    vec = alloca(count * sizeof(struct iovec));
1559
    target_vec = tswapl(msgp->msg_iov);
1560
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1561
    msg.msg_iovlen = count;
1562
    msg.msg_iov = vec;
1563

    
1564
    if (send) {
1565
        ret = target_to_host_cmsg(&msg, msgp);
1566
        if (ret == 0)
1567
            ret = get_errno(sendmsg(fd, &msg, flags));
1568
    } else {
1569
        ret = get_errno(recvmsg(fd, &msg, flags));
1570
        if (!is_error(ret)) {
1571
            len = ret;
1572
            ret = host_to_target_cmsg(msgp, &msg);
1573
            if (!is_error(ret))
1574
                ret = len;
1575
        }
1576
    }
1577
    unlock_iovec(vec, target_vec, count, !send);
1578
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1579
    return ret;
1580
}
1581

    
1582
/* do_accept() Must return target values and target errnos. */
1583
static abi_long do_accept(int fd, abi_ulong target_addr,
1584
                          abi_ulong target_addrlen_addr)
1585
{
1586
    socklen_t addrlen;
1587
    void *addr;
1588
    abi_long ret;
1589

    
1590
    if (get_user_u32(addrlen, target_addrlen_addr))
1591
        return -TARGET_EFAULT;
1592

    
1593
    if (addrlen < 0)
1594
        return -TARGET_EINVAL;
1595

    
1596
    addr = alloca(addrlen);
1597

    
1598
    ret = get_errno(accept(fd, addr, &addrlen));
1599
    if (!is_error(ret)) {
1600
        host_to_target_sockaddr(target_addr, addr, addrlen);
1601
        if (put_user_u32(addrlen, target_addrlen_addr))
1602
            ret = -TARGET_EFAULT;
1603
    }
1604
    return ret;
1605
}
1606

    
1607
/* do_getpeername() Must return target values and target errnos. */
1608
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1609
                               abi_ulong target_addrlen_addr)
1610
{
1611
    socklen_t addrlen;
1612
    void *addr;
1613
    abi_long ret;
1614

    
1615
    if (get_user_u32(addrlen, target_addrlen_addr))
1616
        return -TARGET_EFAULT;
1617

    
1618
    if (addrlen < 0)
1619
        return -TARGET_EINVAL;
1620

    
1621
    addr = alloca(addrlen);
1622

    
1623
    ret = get_errno(getpeername(fd, addr, &addrlen));
1624
    if (!is_error(ret)) {
1625
        host_to_target_sockaddr(target_addr, addr, addrlen);
1626
        if (put_user_u32(addrlen, target_addrlen_addr))
1627
            ret = -TARGET_EFAULT;
1628
    }
1629
    return ret;
1630
}
1631

    
1632
/* do_getsockname() Must return target values and target errnos. */
1633
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1634
                               abi_ulong target_addrlen_addr)
1635
{
1636
    socklen_t addrlen;
1637
    void *addr;
1638
    abi_long ret;
1639

    
1640
    if (target_addr == 0)
1641
       return get_errno(accept(fd, NULL, NULL));
1642

    
1643
    if (get_user_u32(addrlen, target_addrlen_addr))
1644
        return -TARGET_EFAULT;
1645

    
1646
    if (addrlen < 0)
1647
        return -TARGET_EINVAL;
1648

    
1649
    addr = alloca(addrlen);
1650

    
1651
    ret = get_errno(getsockname(fd, addr, &addrlen));
1652
    if (!is_error(ret)) {
1653
        host_to_target_sockaddr(target_addr, addr, addrlen);
1654
        if (put_user_u32(addrlen, target_addrlen_addr))
1655
            ret = -TARGET_EFAULT;
1656
    }
1657
    return ret;
1658
}
1659

    
1660
/* do_socketpair() Must return target values and target errnos. */
1661
static abi_long do_socketpair(int domain, int type, int protocol,
1662
                              abi_ulong target_tab_addr)
1663
{
1664
    int tab[2];
1665
    abi_long ret;
1666

    
1667
    ret = get_errno(socketpair(domain, type, protocol, tab));
1668
    if (!is_error(ret)) {
1669
        if (put_user_s32(tab[0], target_tab_addr)
1670
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1671
            ret = -TARGET_EFAULT;
1672
    }
1673
    return ret;
1674
}
1675

    
1676
/* do_sendto() Must return target values and target errnos. */
1677
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1678
                          abi_ulong target_addr, socklen_t addrlen)
1679
{
1680
    void *addr;
1681
    void *host_msg;
1682
    abi_long ret;
1683

    
1684
    if (addrlen < 0)
1685
        return -TARGET_EINVAL;
1686

    
1687
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1688
    if (!host_msg)
1689
        return -TARGET_EFAULT;
1690
    if (target_addr) {
1691
        addr = alloca(addrlen);
1692
        target_to_host_sockaddr(addr, target_addr, addrlen);
1693
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1694
    } else {
1695
        ret = get_errno(send(fd, host_msg, len, flags));
1696
    }
1697
    unlock_user(host_msg, msg, 0);
1698
    return ret;
1699
}
1700

    
1701
/* do_recvfrom() Must return target values and target errnos. */
1702
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1703
                            abi_ulong target_addr,
1704
                            abi_ulong target_addrlen)
1705
{
1706
    socklen_t addrlen;
1707
    void *addr;
1708
    void *host_msg;
1709
    abi_long ret;
1710

    
1711
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1712
    if (!host_msg)
1713
        return -TARGET_EFAULT;
1714
    if (target_addr) {
1715
        if (get_user_u32(addrlen, target_addrlen)) {
1716
            ret = -TARGET_EFAULT;
1717
            goto fail;
1718
        }
1719
        if (addrlen < 0) {
1720
            ret = -TARGET_EINVAL;
1721
            goto fail;
1722
        }
1723
        addr = alloca(addrlen);
1724
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1725
    } else {
1726
        addr = NULL; /* To keep compiler quiet.  */
1727
        ret = get_errno(recv(fd, host_msg, len, flags));
1728
    }
1729
    if (!is_error(ret)) {
1730
        if (target_addr) {
1731
            host_to_target_sockaddr(target_addr, addr, addrlen);
1732
            if (put_user_u32(addrlen, target_addrlen)) {
1733
                ret = -TARGET_EFAULT;
1734
                goto fail;
1735
            }
1736
        }
1737
        unlock_user(host_msg, msg, len);
1738
    } else {
1739
fail:
1740
        unlock_user(host_msg, msg, 0);
1741
    }
1742
    return ret;
1743
}
1744

    
1745
#ifdef TARGET_NR_socketcall
1746
/* do_socketcall() Must return target values and target errnos. */
1747
static abi_long do_socketcall(int num, abi_ulong vptr)
1748
{
1749
    abi_long ret;
1750
    const int n = sizeof(abi_ulong);
1751

    
1752
    switch(num) {
1753
    case SOCKOP_socket:
1754
        {
1755
            int domain, type, protocol;
1756

    
1757
            if (get_user_s32(domain, vptr)
1758
                || get_user_s32(type, vptr + n)
1759
                || get_user_s32(protocol, vptr + 2 * n))
1760
                return -TARGET_EFAULT;
1761

    
1762
            ret = do_socket(domain, type, protocol);
1763
        }
1764
        break;
1765
    case SOCKOP_bind:
1766
        {
1767
            int sockfd;
1768
            abi_ulong target_addr;
1769
            socklen_t addrlen;
1770

    
1771
            if (get_user_s32(sockfd, vptr)
1772
                || get_user_ual(target_addr, vptr + n)
1773
                || get_user_u32(addrlen, vptr + 2 * n))
1774
                return -TARGET_EFAULT;
1775

    
1776
            ret = do_bind(sockfd, target_addr, addrlen);
1777
        }
1778
        break;
1779
    case SOCKOP_connect:
1780
        {
1781
            int sockfd;
1782
            abi_ulong target_addr;
1783
            socklen_t addrlen;
1784

    
1785
            if (get_user_s32(sockfd, vptr)
1786
                || get_user_ual(target_addr, vptr + n)
1787
                || get_user_u32(addrlen, vptr + 2 * n))
1788
                return -TARGET_EFAULT;
1789

    
1790
            ret = do_connect(sockfd, target_addr, addrlen);
1791
        }
1792
        break;
1793
    case SOCKOP_listen:
1794
        {
1795
            int sockfd, backlog;
1796

    
1797
            if (get_user_s32(sockfd, vptr)
1798
                || get_user_s32(backlog, vptr + n))
1799
                return -TARGET_EFAULT;
1800

    
1801
            ret = get_errno(listen(sockfd, backlog));
1802
        }
1803
        break;
1804
    case SOCKOP_accept:
1805
        {
1806
            int sockfd;
1807
            abi_ulong target_addr, target_addrlen;
1808

    
1809
            if (get_user_s32(sockfd, vptr)
1810
                || get_user_ual(target_addr, vptr + n)
1811
                || get_user_u32(target_addrlen, vptr + 2 * n))
1812
                return -TARGET_EFAULT;
1813

    
1814
            ret = do_accept(sockfd, target_addr, target_addrlen);
1815
        }
1816
        break;
1817
    case SOCKOP_getsockname:
1818
        {
1819
            int sockfd;
1820
            abi_ulong target_addr, target_addrlen;
1821

    
1822
            if (get_user_s32(sockfd, vptr)
1823
                || get_user_ual(target_addr, vptr + n)
1824
                || get_user_u32(target_addrlen, vptr + 2 * n))
1825
                return -TARGET_EFAULT;
1826

    
1827
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1828
        }
1829
        break;
1830
    case SOCKOP_getpeername:
1831
        {
1832
            int sockfd;
1833
            abi_ulong target_addr, target_addrlen;
1834

    
1835
            if (get_user_s32(sockfd, vptr)
1836
                || get_user_ual(target_addr, vptr + n)
1837
                || get_user_u32(target_addrlen, vptr + 2 * n))
1838
                return -TARGET_EFAULT;
1839

    
1840
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1841
        }
1842
        break;
1843
    case SOCKOP_socketpair:
1844
        {
1845
            int domain, type, protocol;
1846
            abi_ulong tab;
1847

    
1848
            if (get_user_s32(domain, vptr)
1849
                || get_user_s32(type, vptr + n)
1850
                || get_user_s32(protocol, vptr + 2 * n)
1851
                || get_user_ual(tab, vptr + 3 * n))
1852
                return -TARGET_EFAULT;
1853

    
1854
            ret = do_socketpair(domain, type, protocol, tab);
1855
        }
1856
        break;
1857
    case SOCKOP_send:
1858
        {
1859
            int sockfd;
1860
            abi_ulong msg;
1861
            size_t len;
1862
            int flags;
1863

    
1864
            if (get_user_s32(sockfd, vptr)
1865
                || get_user_ual(msg, vptr + n)
1866
                || get_user_ual(len, vptr + 2 * n)
1867
                || get_user_s32(flags, vptr + 3 * n))
1868
                return -TARGET_EFAULT;
1869

    
1870
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1871
        }
1872
        break;
1873
    case SOCKOP_recv:
1874
        {
1875
            int sockfd;
1876
            abi_ulong msg;
1877
            size_t len;
1878
            int flags;
1879

    
1880
            if (get_user_s32(sockfd, vptr)
1881
                || get_user_ual(msg, vptr + n)
1882
                || get_user_ual(len, vptr + 2 * n)
1883
                || get_user_s32(flags, vptr + 3 * n))
1884
                return -TARGET_EFAULT;
1885

    
1886
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1887
        }
1888
        break;
1889
    case SOCKOP_sendto:
1890
        {
1891
            int sockfd;
1892
            abi_ulong msg;
1893
            size_t len;
1894
            int flags;
1895
            abi_ulong addr;
1896
            socklen_t addrlen;
1897

    
1898
            if (get_user_s32(sockfd, vptr)
1899
                || get_user_ual(msg, vptr + n)
1900
                || get_user_ual(len, vptr + 2 * n)
1901
                || get_user_s32(flags, vptr + 3 * n)
1902
                || get_user_ual(addr, vptr + 4 * n)
1903
                || get_user_u32(addrlen, vptr + 5 * n))
1904
                return -TARGET_EFAULT;
1905

    
1906
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1907
        }
1908
        break;
1909
    case SOCKOP_recvfrom:
1910
        {
1911
            int sockfd;
1912
            abi_ulong msg;
1913
            size_t len;
1914
            int flags;
1915
            abi_ulong addr;
1916
            socklen_t addrlen;
1917

    
1918
            if (get_user_s32(sockfd, vptr)
1919
                || get_user_ual(msg, vptr + n)
1920
                || get_user_ual(len, vptr + 2 * n)
1921
                || get_user_s32(flags, vptr + 3 * n)
1922
                || get_user_ual(addr, vptr + 4 * n)
1923
                || get_user_u32(addrlen, vptr + 5 * n))
1924
                return -TARGET_EFAULT;
1925

    
1926
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1927
        }
1928
        break;
1929
    case SOCKOP_shutdown:
1930
        {
1931
            int sockfd, how;
1932

    
1933
            if (get_user_s32(sockfd, vptr)
1934
                || get_user_s32(how, vptr + n))
1935
                return -TARGET_EFAULT;
1936

    
1937
            ret = get_errno(shutdown(sockfd, how));
1938
        }
1939
        break;
1940
    case SOCKOP_sendmsg:
1941
    case SOCKOP_recvmsg:
1942
        {
1943
            int fd;
1944
            abi_ulong target_msg;
1945
            int flags;
1946

    
1947
            if (get_user_s32(fd, vptr)
1948
                || get_user_ual(target_msg, vptr + n)
1949
                || get_user_s32(flags, vptr + 2 * n))
1950
                return -TARGET_EFAULT;
1951

    
1952
            ret = do_sendrecvmsg(fd, target_msg, flags,
1953
                                 (num == SOCKOP_sendmsg));
1954
        }
1955
        break;
1956
    case SOCKOP_setsockopt:
1957
        {
1958
            int sockfd;
1959
            int level;
1960
            int optname;
1961
            abi_ulong optval;
1962
            socklen_t optlen;
1963

    
1964
            if (get_user_s32(sockfd, vptr)
1965
                || get_user_s32(level, vptr + n)
1966
                || get_user_s32(optname, vptr + 2 * n)
1967
                || get_user_ual(optval, vptr + 3 * n)
1968
                || get_user_u32(optlen, vptr + 4 * n))
1969
                return -TARGET_EFAULT;
1970

    
1971
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1972
        }
1973
        break;
1974
    case SOCKOP_getsockopt:
1975
        {
1976
            int sockfd;
1977
            int level;
1978
            int optname;
1979
            abi_ulong optval;
1980
            socklen_t optlen;
1981

    
1982
            if (get_user_s32(sockfd, vptr)
1983
                || get_user_s32(level, vptr + n)
1984
                || get_user_s32(optname, vptr + 2 * n)
1985
                || get_user_ual(optval, vptr + 3 * n)
1986
                || get_user_u32(optlen, vptr + 4 * n))
1987
                return -TARGET_EFAULT;
1988

    
1989
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1990
        }
1991
        break;
1992
    default:
1993
        gemu_log("Unsupported socketcall: %d\n", num);
1994
        ret = -TARGET_ENOSYS;
1995
        break;
1996
    }
1997
    return ret;
1998
}
1999
#endif
2000

    
2001
#define N_SHM_REGIONS        32
2002

    
2003
static struct shm_region {
2004
    abi_ulong        start;
2005
    abi_ulong        size;
2006
} shm_regions[N_SHM_REGIONS];
2007

    
2008
struct target_ipc_perm
2009
{
2010
    abi_long __key;
2011
    abi_ulong uid;
2012
    abi_ulong gid;
2013
    abi_ulong cuid;
2014
    abi_ulong cgid;
2015
    unsigned short int mode;
2016
    unsigned short int __pad1;
2017
    unsigned short int __seq;
2018
    unsigned short int __pad2;
2019
    abi_ulong __unused1;
2020
    abi_ulong __unused2;
2021
};
2022

    
2023
struct target_semid_ds
2024
{
2025
  struct target_ipc_perm sem_perm;
2026
  abi_ulong sem_otime;
2027
  abi_ulong __unused1;
2028
  abi_ulong sem_ctime;
2029
  abi_ulong __unused2;
2030
  abi_ulong sem_nsems;
2031
  abi_ulong __unused3;
2032
  abi_ulong __unused4;
2033
};
2034

    
2035
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2036
                                               abi_ulong target_addr)
2037
{
2038
    struct target_ipc_perm *target_ip;
2039
    struct target_semid_ds *target_sd;
2040

    
2041
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2042
        return -TARGET_EFAULT;
2043
    target_ip=&(target_sd->sem_perm);
2044
    host_ip->__key = tswapl(target_ip->__key);
2045
    host_ip->uid = tswapl(target_ip->uid);
2046
    host_ip->gid = tswapl(target_ip->gid);
2047
    host_ip->cuid = tswapl(target_ip->cuid);
2048
    host_ip->cgid = tswapl(target_ip->cgid);
2049
    host_ip->mode = tswapl(target_ip->mode);
2050
    unlock_user_struct(target_sd, target_addr, 0);
2051
    return 0;
2052
}
2053

    
2054
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2055
                                               struct ipc_perm *host_ip)
2056
{
2057
    struct target_ipc_perm *target_ip;
2058
    struct target_semid_ds *target_sd;
2059

    
2060
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2061
        return -TARGET_EFAULT;
2062
    target_ip = &(target_sd->sem_perm);
2063
    target_ip->__key = tswapl(host_ip->__key);
2064
    target_ip->uid = tswapl(host_ip->uid);
2065
    target_ip->gid = tswapl(host_ip->gid);
2066
    target_ip->cuid = tswapl(host_ip->cuid);
2067
    target_ip->cgid = tswapl(host_ip->cgid);
2068
    target_ip->mode = tswapl(host_ip->mode);
2069
    unlock_user_struct(target_sd, target_addr, 1);
2070
    return 0;
2071
}
2072

    
2073
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2074
                                               abi_ulong target_addr)
2075
{
2076
    struct target_semid_ds *target_sd;
2077

    
2078
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2079
        return -TARGET_EFAULT;
2080
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2081
        return -TARGET_EFAULT;
2082
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2083
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2084
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2085
    unlock_user_struct(target_sd, target_addr, 0);
2086
    return 0;
2087
}
2088

    
2089
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2090
                                               struct semid_ds *host_sd)
2091
{
2092
    struct target_semid_ds *target_sd;
2093

    
2094
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2095
        return -TARGET_EFAULT;
2096
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2097
        return -TARGET_EFAULT;;
2098
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2099
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2100
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2101
    unlock_user_struct(target_sd, target_addr, 1);
2102
    return 0;
2103
}
2104

    
2105
struct target_seminfo {
2106
    int semmap;
2107
    int semmni;
2108
    int semmns;
2109
    int semmnu;
2110
    int semmsl;
2111
    int semopm;
2112
    int semume;
2113
    int semusz;
2114
    int semvmx;
2115
    int semaem;
2116
};
2117

    
2118
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2119
                                              struct seminfo *host_seminfo)
2120
{
2121
    struct target_seminfo *target_seminfo;
2122
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2123
        return -TARGET_EFAULT;
2124
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2125
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2126
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2127
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2128
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2129
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2130
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2131
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2132
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2133
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2134
    unlock_user_struct(target_seminfo, target_addr, 1);
2135
    return 0;
2136
}
2137

    
2138
union semun {
2139
        int val;
2140
        struct semid_ds *buf;
2141
        unsigned short *array;
2142
        struct seminfo *__buf;
2143
};
2144

    
2145
union target_semun {
2146
        int val;
2147
        abi_ulong buf;
2148
        abi_ulong array;
2149
        abi_ulong __buf;
2150
};
2151

    
2152
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2153
                                               abi_ulong target_addr)
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
    *host_array = malloc(nsems*sizeof(unsigned short));
2170
    array = lock_user(VERIFY_READ, target_addr,
2171
                      nsems*sizeof(unsigned short), 1);
2172
    if (!array)
2173
        return -TARGET_EFAULT;
2174

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

    
2180
    return 0;
2181
}
2182

    
2183
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2184
                                               unsigned short **host_array)
2185
{
2186
    int nsems;
2187
    unsigned short *array;
2188
    union semun semun;
2189
    struct semid_ds semid_ds;
2190
    int i, ret;
2191

    
2192
    semun.buf = &semid_ds;
2193

    
2194
    ret = semctl(semid, 0, IPC_STAT, semun);
2195
    if (ret == -1)
2196
        return get_errno(ret);
2197

    
2198
    nsems = semid_ds.sem_nsems;
2199

    
2200
    array = lock_user(VERIFY_WRITE, target_addr,
2201
                      nsems*sizeof(unsigned short), 0);
2202
    if (!array)
2203
        return -TARGET_EFAULT;
2204

    
2205
    for(i=0; i<nsems; i++) {
2206
        __put_user((*host_array)[i], &array[i]);
2207
    }
2208
    free(*host_array);
2209
    unlock_user(array, target_addr, 1);
2210

    
2211
    return 0;
2212
}
2213

    
2214
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2215
                                 union target_semun target_su)
2216
{
2217
    union semun arg;
2218
    struct semid_ds dsarg;
2219
    unsigned short *array;
2220
    struct seminfo seminfo;
2221
    abi_long ret = -TARGET_EINVAL;
2222
    abi_long err;
2223
    cmd &= 0xff;
2224

    
2225
    switch( cmd ) {
2226
        case GETVAL:
2227
        case SETVAL:
2228
            arg.val = tswapl(target_su.val);
2229
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2230
            target_su.val = tswapl(arg.val);
2231
            break;
2232
        case GETALL:
2233
        case SETALL:
2234
            err = target_to_host_semarray(semid, &array, target_su.array);
2235
            if (err)
2236
                return err;
2237
            arg.array = array;
2238
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2239
            err = host_to_target_semarray(semid, target_su.array, &array);
2240
            if (err)
2241
                return err;
2242
            break;
2243
        case IPC_STAT:
2244
        case IPC_SET:
2245
        case SEM_STAT:
2246
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2247
            if (err)
2248
                return err;
2249
            arg.buf = &dsarg;
2250
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2251
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2252
            if (err)
2253
                return err;
2254
            break;
2255
        case IPC_INFO:
2256
        case SEM_INFO:
2257
            arg.__buf = &seminfo;
2258
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2259
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2260
            if (err)
2261
                return err;
2262
            break;
2263
        case IPC_RMID:
2264
        case GETPID:
2265
        case GETNCNT:
2266
        case GETZCNT:
2267
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2268
            break;
2269
    }
2270

    
2271
    return ret;
2272
}
2273

    
2274
struct target_sembuf {
2275
    unsigned short sem_num;
2276
    short sem_op;
2277
    short sem_flg;
2278
};
2279

    
2280
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2281
                                             abi_ulong target_addr,
2282
                                             unsigned nsops)
2283
{
2284
    struct target_sembuf *target_sembuf;
2285
    int i;
2286

    
2287
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2288
                              nsops*sizeof(struct target_sembuf), 1);
2289
    if (!target_sembuf)
2290
        return -TARGET_EFAULT;
2291

    
2292
    for(i=0; i<nsops; i++) {
2293
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2294
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2295
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2296
    }
2297

    
2298
    unlock_user(target_sembuf, target_addr, 0);
2299

    
2300
    return 0;
2301
}
2302

    
2303
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2304
{
2305
    struct sembuf sops[nsops];
2306

    
2307
    if (target_to_host_sembuf(sops, ptr, nsops))
2308
        return -TARGET_EFAULT;
2309

    
2310
    return semop(semid, sops, nsops);
2311
}
2312

    
2313
struct target_msqid_ds
2314
{
2315
    struct target_ipc_perm msg_perm;
2316
    abi_ulong msg_stime;
2317
#if TARGET_ABI_BITS == 32
2318
    abi_ulong __unused1;
2319
#endif
2320
    abi_ulong msg_rtime;
2321
#if TARGET_ABI_BITS == 32
2322
    abi_ulong __unused2;
2323
#endif
2324
    abi_ulong msg_ctime;
2325
#if TARGET_ABI_BITS == 32
2326
    abi_ulong __unused3;
2327
#endif
2328
    abi_ulong __msg_cbytes;
2329
    abi_ulong msg_qnum;
2330
    abi_ulong msg_qbytes;
2331
    abi_ulong msg_lspid;
2332
    abi_ulong msg_lrpid;
2333
    abi_ulong __unused4;
2334
    abi_ulong __unused5;
2335
};
2336

    
2337
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2338
                                               abi_ulong target_addr)
2339
{
2340
    struct target_msqid_ds *target_md;
2341

    
2342
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2343
        return -TARGET_EFAULT;
2344
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2345
        return -TARGET_EFAULT;
2346
    host_md->msg_stime = tswapl(target_md->msg_stime);
2347
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2348
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2349
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2350
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2351
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2352
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2353
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2354
    unlock_user_struct(target_md, target_addr, 0);
2355
    return 0;
2356
}
2357

    
2358
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2359
                                               struct msqid_ds *host_md)
2360
{
2361
    struct target_msqid_ds *target_md;
2362

    
2363
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2364
        return -TARGET_EFAULT;
2365
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2366
        return -TARGET_EFAULT;
2367
    target_md->msg_stime = tswapl(host_md->msg_stime);
2368
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2369
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2370
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2371
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2372
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2373
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2374
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2375
    unlock_user_struct(target_md, target_addr, 1);
2376
    return 0;
2377
}
2378

    
2379
struct target_msginfo {
2380
    int msgpool;
2381
    int msgmap;
2382
    int msgmax;
2383
    int msgmnb;
2384
    int msgmni;
2385
    int msgssz;
2386
    int msgtql;
2387
    unsigned short int msgseg;
2388
};
2389

    
2390
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2391
                                              struct msginfo *host_msginfo)
2392
{
2393
    struct target_msginfo *target_msginfo;
2394
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2395
        return -TARGET_EFAULT;
2396
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2397
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2398
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2399
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2400
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2401
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2402
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2403
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2404
    unlock_user_struct(target_msginfo, target_addr, 1);
2405
    return 0;
2406
}
2407

    
2408
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2409
{
2410
    struct msqid_ds dsarg;
2411
    struct msginfo msginfo;
2412
    abi_long ret = -TARGET_EINVAL;
2413

    
2414
    cmd &= 0xff;
2415

    
2416
    switch (cmd) {
2417
    case IPC_STAT:
2418
    case IPC_SET:
2419
    case MSG_STAT:
2420
        if (target_to_host_msqid_ds(&dsarg,ptr))
2421
            return -TARGET_EFAULT;
2422
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2423
        if (host_to_target_msqid_ds(ptr,&dsarg))
2424
            return -TARGET_EFAULT;
2425
        break;
2426
    case IPC_RMID:
2427
        ret = get_errno(msgctl(msgid, cmd, NULL));
2428
        break;
2429
    case IPC_INFO:
2430
    case MSG_INFO:
2431
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2432
        if (host_to_target_msginfo(ptr, &msginfo))
2433
            return -TARGET_EFAULT;
2434
        break;
2435
    }
2436

    
2437
    return ret;
2438
}
2439

    
2440
struct target_msgbuf {
2441
    abi_long mtype;
2442
    char        mtext[1];
2443
};
2444

    
2445
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2446
                                 unsigned int msgsz, int msgflg)
2447
{
2448
    struct target_msgbuf *target_mb;
2449
    struct msgbuf *host_mb;
2450
    abi_long ret = 0;
2451

    
2452
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2453
        return -TARGET_EFAULT;
2454
    host_mb = malloc(msgsz+sizeof(long));
2455
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2456
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2457
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2458
    free(host_mb);
2459
    unlock_user_struct(target_mb, msgp, 0);
2460

    
2461
    return ret;
2462
}
2463

    
2464
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2465
                                 unsigned int msgsz, abi_long msgtyp,
2466
                                 int msgflg)
2467
{
2468
    struct target_msgbuf *target_mb;
2469
    char *target_mtext;
2470
    struct msgbuf *host_mb;
2471
    abi_long ret = 0;
2472

    
2473
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2474
        return -TARGET_EFAULT;
2475

    
2476
    host_mb = malloc(msgsz+sizeof(long));
2477
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2478

    
2479
    if (ret > 0) {
2480
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2481
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2482
        if (!target_mtext) {
2483
            ret = -TARGET_EFAULT;
2484
            goto end;
2485
        }
2486
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2487
        unlock_user(target_mtext, target_mtext_addr, ret);
2488
    }
2489

    
2490
    target_mb->mtype = tswapl(host_mb->mtype);
2491
    free(host_mb);
2492

    
2493
end:
2494
    if (target_mb)
2495
        unlock_user_struct(target_mb, msgp, 1);
2496
    return ret;
2497
}
2498

    
2499
struct target_shmid_ds
2500
{
2501
    struct target_ipc_perm shm_perm;
2502
    abi_ulong shm_segsz;
2503
    abi_ulong shm_atime;
2504
#if TARGET_ABI_BITS == 32
2505
    abi_ulong __unused1;
2506
#endif
2507
    abi_ulong shm_dtime;
2508
#if TARGET_ABI_BITS == 32
2509
    abi_ulong __unused2;
2510
#endif
2511
    abi_ulong shm_ctime;
2512
#if TARGET_ABI_BITS == 32
2513
    abi_ulong __unused3;
2514
#endif
2515
    int shm_cpid;
2516
    int shm_lpid;
2517
    abi_ulong shm_nattch;
2518
    unsigned long int __unused4;
2519
    unsigned long int __unused5;
2520
};
2521

    
2522
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2523
                                               abi_ulong target_addr)
2524
{
2525
    struct target_shmid_ds *target_sd;
2526

    
2527
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2528
        return -TARGET_EFAULT;
2529
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2530
        return -TARGET_EFAULT;
2531
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2532
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2533
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2534
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2535
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2536
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2537
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2538
    unlock_user_struct(target_sd, target_addr, 0);
2539
    return 0;
2540
}
2541

    
2542
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2543
                                               struct shmid_ds *host_sd)
2544
{
2545
    struct target_shmid_ds *target_sd;
2546

    
2547
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2548
        return -TARGET_EFAULT;
2549
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2550
        return -TARGET_EFAULT;
2551
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2552
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2553
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2554
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2555
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2556
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2557
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2558
    unlock_user_struct(target_sd, target_addr, 1);
2559
    return 0;
2560
}
2561

    
2562
struct  target_shminfo {
2563
    abi_ulong shmmax;
2564
    abi_ulong shmmin;
2565
    abi_ulong shmmni;
2566
    abi_ulong shmseg;
2567
    abi_ulong shmall;
2568
};
2569

    
2570
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2571
                                              struct shminfo *host_shminfo)
2572
{
2573
    struct target_shminfo *target_shminfo;
2574
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2575
        return -TARGET_EFAULT;
2576
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2577
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2578
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2579
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2580
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2581
    unlock_user_struct(target_shminfo, target_addr, 1);
2582
    return 0;
2583
}
2584

    
2585
struct target_shm_info {
2586
    int used_ids;
2587
    abi_ulong shm_tot;
2588
    abi_ulong shm_rss;
2589
    abi_ulong shm_swp;
2590
    abi_ulong swap_attempts;
2591
    abi_ulong swap_successes;
2592
};
2593

    
2594
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2595
                                               struct shm_info *host_shm_info)
2596
{
2597
    struct target_shm_info *target_shm_info;
2598
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2599
        return -TARGET_EFAULT;
2600
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2601
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2602
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2603
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2604
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2605
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2606
    unlock_user_struct(target_shm_info, target_addr, 1);
2607
    return 0;
2608
}
2609

    
2610
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2611
{
2612
    struct shmid_ds dsarg;
2613
    struct shminfo shminfo;
2614
    struct shm_info shm_info;
2615
    abi_long ret = -TARGET_EINVAL;
2616

    
2617
    cmd &= 0xff;
2618

    
2619
    switch(cmd) {
2620
    case IPC_STAT:
2621
    case IPC_SET:
2622
    case SHM_STAT:
2623
        if (target_to_host_shmid_ds(&dsarg, buf))
2624
            return -TARGET_EFAULT;
2625
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2626
        if (host_to_target_shmid_ds(buf, &dsarg))
2627
            return -TARGET_EFAULT;
2628
        break;
2629
    case IPC_INFO:
2630
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2631
        if (host_to_target_shminfo(buf, &shminfo))
2632
            return -TARGET_EFAULT;
2633
        break;
2634
    case SHM_INFO:
2635
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2636
        if (host_to_target_shm_info(buf, &shm_info))
2637
            return -TARGET_EFAULT;
2638
        break;
2639
    case IPC_RMID:
2640
    case SHM_LOCK:
2641
    case SHM_UNLOCK:
2642
        ret = get_errno(shmctl(shmid, cmd, NULL));
2643
        break;
2644
    }
2645

    
2646
    return ret;
2647
}
2648

    
2649
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2650
{
2651
    abi_long raddr;
2652
    void *host_raddr;
2653
    struct shmid_ds shm_info;
2654
    int i,ret;
2655

    
2656
    /* find out the length of the shared memory segment */
2657
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2658
    if (is_error(ret)) {
2659
        /* can't get length, bail out */
2660
        return ret;
2661
    }
2662

    
2663
    mmap_lock();
2664

    
2665
    if (shmaddr)
2666
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2667
    else {
2668
        abi_ulong mmap_start;
2669

    
2670
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2671

    
2672
        if (mmap_start == -1) {
2673
            errno = ENOMEM;
2674
            host_raddr = (void *)-1;
2675
        } else
2676
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2677
    }
2678

    
2679
    if (host_raddr == (void *)-1) {
2680
        mmap_unlock();
2681
        return get_errno((long)host_raddr);
2682
    }
2683
    raddr=h2g((unsigned long)host_raddr);
2684

    
2685
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2686
                   PAGE_VALID | PAGE_READ |
2687
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2688

    
2689
    for (i = 0; i < N_SHM_REGIONS; i++) {
2690
        if (shm_regions[i].start == 0) {
2691
            shm_regions[i].start = raddr;
2692
            shm_regions[i].size = shm_info.shm_segsz;
2693
            break;
2694
        }
2695
    }
2696

    
2697
    mmap_unlock();
2698
    return raddr;
2699

    
2700
}
2701

    
2702
static inline abi_long do_shmdt(abi_ulong shmaddr)
2703
{
2704
    int i;
2705

    
2706
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2707
        if (shm_regions[i].start == shmaddr) {
2708
            shm_regions[i].start = 0;
2709
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2710
            break;
2711
        }
2712
    }
2713

    
2714
    return get_errno(shmdt(g2h(shmaddr)));
2715
}
2716

    
2717
#ifdef TARGET_NR_ipc
2718
/* ??? This only works with linear mappings.  */
2719
/* do_ipc() must return target values and target errnos. */
2720
static abi_long do_ipc(unsigned int call, int first,
2721
                       int second, int third,
2722
                       abi_long ptr, abi_long fifth)
2723
{
2724
    int version;
2725
    abi_long ret = 0;
2726

    
2727
    version = call >> 16;
2728
    call &= 0xffff;
2729

    
2730
    switch (call) {
2731
    case IPCOP_semop:
2732
        ret = do_semop(first, ptr, second);
2733
        break;
2734

    
2735
    case IPCOP_semget:
2736
        ret = get_errno(semget(first, second, third));
2737
        break;
2738

    
2739
    case IPCOP_semctl:
2740
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2741
        break;
2742

    
2743
    case IPCOP_msgget:
2744
        ret = get_errno(msgget(first, second));
2745
        break;
2746

    
2747
    case IPCOP_msgsnd:
2748
        ret = do_msgsnd(first, ptr, second, third);
2749
        break;
2750

    
2751
    case IPCOP_msgctl:
2752
        ret = do_msgctl(first, second, ptr);
2753
        break;
2754

    
2755
    case IPCOP_msgrcv:
2756
        switch (version) {
2757
        case 0:
2758
            {
2759
                struct target_ipc_kludge {
2760
                    abi_long msgp;
2761
                    abi_long msgtyp;
2762
                } *tmp;
2763

    
2764
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2765
                    ret = -TARGET_EFAULT;
2766
                    break;
2767
                }
2768

    
2769
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2770

    
2771
                unlock_user_struct(tmp, ptr, 0);
2772
                break;
2773
            }
2774
        default:
2775
            ret = do_msgrcv(first, ptr, second, fifth, third);
2776
        }
2777
        break;
2778

    
2779
    case IPCOP_shmat:
2780
        switch (version) {
2781
        default:
2782
        {
2783
            abi_ulong raddr;
2784
            raddr = do_shmat(first, ptr, second);
2785
            if (is_error(raddr))
2786
                return get_errno(raddr);
2787
            if (put_user_ual(raddr, third))
2788
                return -TARGET_EFAULT;
2789
            break;
2790
        }
2791
        case 1:
2792
            ret = -TARGET_EINVAL;
2793
            break;
2794
        }
2795
        break;
2796
    case IPCOP_shmdt:
2797
        ret = do_shmdt(ptr);
2798
        break;
2799

    
2800
    case IPCOP_shmget:
2801
        /* IPC_* flag values are the same on all linux platforms */
2802
        ret = get_errno(shmget(first, second, third));
2803
        break;
2804

    
2805
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2806
    case IPCOP_shmctl:
2807
        ret = do_shmctl(first, second, third);
2808
        break;
2809
    default:
2810
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2811
        ret = -TARGET_ENOSYS;
2812
        break;
2813
    }
2814
    return ret;
2815
}
2816
#endif
2817

    
2818
/* kernel structure types definitions */
2819
#define IFNAMSIZ        16
2820

    
2821
#define STRUCT(name, ...) STRUCT_ ## name,
2822
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2823
enum {
2824
#include "syscall_types.h"
2825
};
2826
#undef STRUCT
2827
#undef STRUCT_SPECIAL
2828

    
2829
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2830
#define STRUCT_SPECIAL(name)
2831
#include "syscall_types.h"
2832
#undef STRUCT
2833
#undef STRUCT_SPECIAL
2834

    
2835
typedef struct IOCTLEntry {
2836
    unsigned int target_cmd;
2837
    unsigned int host_cmd;
2838
    const char *name;
2839
    int access;
2840
    const argtype arg_type[5];
2841
} IOCTLEntry;
2842

    
2843
#define IOC_R 0x0001
2844
#define IOC_W 0x0002
2845
#define IOC_RW (IOC_R | IOC_W)
2846

    
2847
#define MAX_STRUCT_SIZE 4096
2848

    
2849
static IOCTLEntry ioctl_entries[] = {
2850
#define IOCTL(cmd, access, ...) \
2851
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2852
#include "ioctls.h"
2853
    { 0, 0, },
2854
};
2855

    
2856
/* ??? Implement proper locking for ioctls.  */
2857
/* do_ioctl() Must return target values and target errnos. */
2858
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2859
{
2860
    const IOCTLEntry *ie;
2861
    const argtype *arg_type;
2862
    abi_long ret;
2863
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2864
    int target_size;
2865
    void *argptr;
2866

    
2867
    ie = ioctl_entries;
2868
    for(;;) {
2869
        if (ie->target_cmd == 0) {
2870
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2871
            return -TARGET_ENOSYS;
2872
        }
2873
        if (ie->target_cmd == cmd)
2874
            break;
2875
        ie++;
2876
    }
2877
    arg_type = ie->arg_type;
2878
#if defined(DEBUG)
2879
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2880
#endif
2881
    switch(arg_type[0]) {
2882
    case TYPE_NULL:
2883
        /* no argument */
2884
        ret = get_errno(ioctl(fd, ie->host_cmd));
2885
        break;
2886
    case TYPE_PTRVOID:
2887
    case TYPE_INT:
2888
        /* int argment */
2889
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2890
        break;
2891
    case TYPE_PTR:
2892
        arg_type++;
2893
        target_size = thunk_type_size(arg_type, 0);
2894
        switch(ie->access) {
2895
        case IOC_R:
2896
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2897
            if (!is_error(ret)) {
2898
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2899
                if (!argptr)
2900
                    return -TARGET_EFAULT;
2901
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2902
                unlock_user(argptr, arg, target_size);
2903
            }
2904
            break;
2905
        case IOC_W:
2906
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2907
            if (!argptr)
2908
                return -TARGET_EFAULT;
2909
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2910
            unlock_user(argptr, arg, 0);
2911
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2912
            break;
2913
        default:
2914
        case IOC_RW:
2915
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2916
            if (!argptr)
2917
                return -TARGET_EFAULT;
2918
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2919
            unlock_user(argptr, arg, 0);
2920
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2921
            if (!is_error(ret)) {
2922
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2923
                if (!argptr)
2924
                    return -TARGET_EFAULT;
2925
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2926
                unlock_user(argptr, arg, target_size);
2927
            }
2928
            break;
2929
        }
2930
        break;
2931
    default:
2932
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2933
                 (long)cmd, arg_type[0]);
2934
        ret = -TARGET_ENOSYS;
2935
        break;
2936
    }
2937
    return ret;
2938
}
2939

    
2940
static const bitmask_transtbl iflag_tbl[] = {
2941
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2942
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2943
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2944
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2945
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2946
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2947
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2948
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2949
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2950
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2951
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2952
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2953
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2954
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2955
        { 0, 0, 0, 0 }
2956
};
2957

    
2958
static const bitmask_transtbl oflag_tbl[] = {
2959
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2960
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2961
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2962
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2963
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2964
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2965
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2966
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2967
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2968
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2969
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2970
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2971
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2972
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2973
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2974
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2975
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2976
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2977
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2978
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2979
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2980
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2981
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2982
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2983
        { 0, 0, 0, 0 }
2984
};
2985

    
2986
static const bitmask_transtbl cflag_tbl[] = {
2987
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2988
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2989
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2990
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2991
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2992
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2993
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2994
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2995
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2996
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2997
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2998
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2999
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3000
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3001
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3002
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3003
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3004
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3005
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3006
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3007
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3008
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3009
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3010
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3011
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3012
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3013
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3014
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3015
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3016
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3017
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3018
        { 0, 0, 0, 0 }
3019
};
3020

    
3021
static const bitmask_transtbl lflag_tbl[] = {
3022
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3023
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3024
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3025
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3026
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3027
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3028
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3029
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3030
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3031
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3032
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3033
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3034
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3035
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3036
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3037
        { 0, 0, 0, 0 }
3038
};
3039

    
3040
static void target_to_host_termios (void *dst, const void *src)
3041
{
3042
    struct host_termios *host = dst;
3043
    const struct target_termios *target = src;
3044

    
3045
    host->c_iflag =
3046
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3047
    host->c_oflag =
3048
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3049
    host->c_cflag =
3050
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3051
    host->c_lflag =
3052
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3053
    host->c_line = target->c_line;
3054

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

    
3075
static void host_to_target_termios (void *dst, const void *src)
3076
{
3077
    struct target_termios *target = dst;
3078
    const struct host_termios *host = src;
3079

    
3080
    target->c_iflag =
3081
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3082
    target->c_oflag =
3083
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3084
    target->c_cflag =
3085
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3086
    target->c_lflag =
3087
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3088
    target->c_line = host->c_line;
3089

    
3090
    memset(target->c_cc, 0, sizeof(target->c_cc));
3091
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3092
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3093
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3094
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3095
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3096
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3097
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3098
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3099
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3100
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3101
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3102
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3103
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3104
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3105
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3106
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3107
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3108
}
3109

    
3110
static const StructEntry struct_termios_def = {
3111
    .convert = { host_to_target_termios, target_to_host_termios },
3112
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3113
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3114
};
3115

    
3116
static bitmask_transtbl mmap_flags_tbl[] = {
3117
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3118
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3119
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3120
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3121
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3122
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3123
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3124
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3125
        { 0, 0, 0, 0 }
3126
};
3127

    
3128
#if defined(TARGET_I386)
3129

    
3130
/* NOTE: there is really one LDT for all the threads */
3131
static uint8_t *ldt_table;
3132

    
3133
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3134
{
3135
    int size;
3136
    void *p;
3137

    
3138
    if (!ldt_table)
3139
        return 0;
3140
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3141
    if (size > bytecount)
3142
        size = bytecount;
3143
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3144
    if (!p)
3145
        return -TARGET_EFAULT;
3146
    /* ??? Should this by byteswapped?  */
3147
    memcpy(p, ldt_table, size);
3148
    unlock_user(p, ptr, size);
3149
    return size;
3150
}
3151

    
3152
/* XXX: add locking support */
3153
static abi_long write_ldt(CPUX86State *env,
3154
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3155
{
3156
    struct target_modify_ldt_ldt_s ldt_info;
3157
    struct target_modify_ldt_ldt_s *target_ldt_info;
3158
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3159
    int seg_not_present, useable, lm;
3160
    uint32_t *lp, entry_1, entry_2;
3161

    
3162
    if (bytecount != sizeof(ldt_info))
3163
        return -TARGET_EINVAL;
3164
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3165
        return -TARGET_EFAULT;
3166
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3167
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3168
    ldt_info.limit = tswap32(target_ldt_info->limit);
3169
    ldt_info.flags = tswap32(target_ldt_info->flags);
3170
    unlock_user_struct(target_ldt_info, ptr, 0);
3171

    
3172
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3173
        return -TARGET_EINVAL;
3174
    seg_32bit = ldt_info.flags & 1;
3175
    contents = (ldt_info.flags >> 1) & 3;
3176
    read_exec_only = (ldt_info.flags >> 3) & 1;
3177
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3178
    seg_not_present = (ldt_info.flags >> 5) & 1;
3179
    useable = (ldt_info.flags >> 6) & 1;
3180
#ifdef TARGET_ABI32
3181
    lm = 0;
3182
#else
3183
    lm = (ldt_info.flags >> 7) & 1;
3184
#endif
3185
    if (contents == 3) {
3186
        if (oldmode)
3187
            return -TARGET_EINVAL;
3188
        if (seg_not_present == 0)
3189
            return -TARGET_EINVAL;
3190
    }
3191
    /* allocate the LDT */
3192
    if (!ldt_table) {
3193
        env->ldt.base = target_mmap(0,
3194
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3195
                                    PROT_READ|PROT_WRITE,
3196
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3197
        if (env->ldt.base == -1)
3198
            return -TARGET_ENOMEM;
3199
        memset(g2h(env->ldt.base), 0,
3200
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3201
        env->ldt.limit = 0xffff;
3202
        ldt_table = g2h(env->ldt.base);
3203
    }
3204

    
3205
    /* NOTE: same code as Linux kernel */
3206
    /* Allow LDTs to be cleared by the user. */
3207
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3208
        if (oldmode ||
3209
            (contents == 0                &&
3210
             read_exec_only == 1        &&
3211
             seg_32bit == 0                &&
3212
             limit_in_pages == 0        &&
3213
             seg_not_present == 1        &&
3214
             useable == 0 )) {
3215
            entry_1 = 0;
3216
            entry_2 = 0;
3217
            goto install;
3218
        }
3219
    }
3220

    
3221
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3222
        (ldt_info.limit & 0x0ffff);
3223
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3224
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3225
        (ldt_info.limit & 0xf0000) |
3226
        ((read_exec_only ^ 1) << 9) |
3227
        (contents << 10) |
3228
        ((seg_not_present ^ 1) << 15) |
3229
        (seg_32bit << 22) |
3230
        (limit_in_pages << 23) |
3231
        (lm << 21) |
3232
        0x7000;
3233
    if (!oldmode)
3234
        entry_2 |= (useable << 20);
3235

    
3236
    /* Install the new entry ...  */
3237
install:
3238
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3239
    lp[0] = tswap32(entry_1);
3240
    lp[1] = tswap32(entry_2);
3241
    return 0;
3242
}
3243

    
3244
/* specific and weird i386 syscalls */
3245
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3246
                              unsigned long bytecount)
3247
{
3248
    abi_long ret;
3249

    
3250
    switch (func) {
3251
    case 0:
3252
        ret = read_ldt(ptr, bytecount);
3253
        break;
3254
    case 1:
3255
        ret = write_ldt(env, ptr, bytecount, 1);
3256
        break;
3257
    case 0x11:
3258
        ret = write_ldt(env, ptr, bytecount, 0);
3259
        break;
3260
    default:
3261
        ret = -TARGET_ENOSYS;
3262
        break;
3263
    }
3264
    return ret;
3265
}
3266

    
3267
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3268
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3269
{
3270
    uint64_t *gdt_table = g2h(env->gdt.base);
3271
    struct target_modify_ldt_ldt_s ldt_info;
3272
    struct target_modify_ldt_ldt_s *target_ldt_info;
3273
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3274
    int seg_not_present, useable, lm;
3275
    uint32_t *lp, entry_1, entry_2;
3276
    int i;
3277

    
3278
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3279
    if (!target_ldt_info)
3280
        return -TARGET_EFAULT;
3281
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3282
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3283
    ldt_info.limit = tswap32(target_ldt_info->limit);
3284
    ldt_info.flags = tswap32(target_ldt_info->flags);
3285
    if (ldt_info.entry_number == -1) {
3286
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3287
            if (gdt_table[i] == 0) {
3288
                ldt_info.entry_number = i;
3289
                target_ldt_info->entry_number = tswap32(i);
3290
                break;
3291
            }
3292
        }
3293
    }
3294
    unlock_user_struct(target_ldt_info, ptr, 1);
3295

    
3296
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3297
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3298
           return -TARGET_EINVAL;
3299
    seg_32bit = ldt_info.flags & 1;
3300
    contents = (ldt_info.flags >> 1) & 3;
3301
    read_exec_only = (ldt_info.flags >> 3) & 1;
3302
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3303
    seg_not_present = (ldt_info.flags >> 5) & 1;
3304
    useable = (ldt_info.flags >> 6) & 1;
3305
#ifdef TARGET_ABI32
3306
    lm = 0;
3307
#else
3308
    lm = (ldt_info.flags >> 7) & 1;
3309
#endif
3310

    
3311
    if (contents == 3) {
3312
        if (seg_not_present == 0)
3313
            return -TARGET_EINVAL;
3314
    }
3315

    
3316
    /* NOTE: same code as Linux kernel */
3317
    /* Allow LDTs to be cleared by the user. */
3318
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3319
        if ((contents == 0             &&
3320
             read_exec_only == 1       &&
3321
             seg_32bit == 0            &&
3322
             limit_in_pages == 0       &&
3323
             seg_not_present == 1      &&
3324
             useable == 0 )) {
3325
            entry_1 = 0;
3326
            entry_2 = 0;
3327
            goto install;
3328
        }
3329
    }
3330

    
3331
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3332
        (ldt_info.limit & 0x0ffff);
3333
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3334
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3335
        (ldt_info.limit & 0xf0000) |
3336
        ((read_exec_only ^ 1) << 9) |
3337
        (contents << 10) |
3338
        ((seg_not_present ^ 1) << 15) |
3339
        (seg_32bit << 22) |
3340
        (limit_in_pages << 23) |
3341
        (useable << 20) |
3342
        (lm << 21) |
3343
        0x7000;
3344

    
3345
    /* Install the new entry ...  */
3346
install:
3347
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3348
    lp[0] = tswap32(entry_1);
3349
    lp[1] = tswap32(entry_2);
3350
    return 0;
3351
}
3352

    
3353
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3354
{
3355
    struct target_modify_ldt_ldt_s *target_ldt_info;
3356
    uint64_t *gdt_table = g2h(env->gdt.base);
3357
    uint32_t base_addr, limit, flags;
3358
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3359
    int seg_not_present, useable, lm;
3360
    uint32_t *lp, entry_1, entry_2;
3361

    
3362
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3363
    if (!target_ldt_info)
3364
        return -TARGET_EFAULT;
3365
    idx = tswap32(target_ldt_info->entry_number);
3366
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3367
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3368
        unlock_user_struct(target_ldt_info, ptr, 1);
3369
        return -TARGET_EINVAL;
3370
    }
3371
    lp = (uint32_t *)(gdt_table + idx);
3372
    entry_1 = tswap32(lp[0]);
3373
    entry_2 = tswap32(lp[1]);
3374
    
3375
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3376
    contents = (entry_2 >> 10) & 3;
3377
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3378
    seg_32bit = (entry_2 >> 22) & 1;
3379
    limit_in_pages = (entry_2 >> 23) & 1;
3380
    useable = (entry_2 >> 20) & 1;
3381
#ifdef TARGET_ABI32
3382
    lm = 0;
3383
#else
3384
    lm = (entry_2 >> 21) & 1;
3385
#endif
3386
    flags = (seg_32bit << 0) | (contents << 1) |
3387
        (read_exec_only << 3) | (limit_in_pages << 4) |
3388
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3389
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3390
    base_addr = (entry_1 >> 16) | 
3391
        (entry_2 & 0xff000000) | 
3392
        ((entry_2 & 0xff) << 16);
3393
    target_ldt_info->base_addr = tswapl(base_addr);
3394
    target_ldt_info->limit = tswap32(limit);
3395
    target_ldt_info->flags = tswap32(flags);
3396
    unlock_user_struct(target_ldt_info, ptr, 1);
3397
    return 0;
3398
}
3399
#endif /* TARGET_I386 && TARGET_ABI32 */
3400

    
3401
#ifndef TARGET_ABI32
3402
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3403
{
3404
    abi_long ret;
3405
    abi_ulong val;
3406
    int idx;
3407
    
3408
    switch(code) {
3409
    case TARGET_ARCH_SET_GS:
3410
    case TARGET_ARCH_SET_FS:
3411
        if (code == TARGET_ARCH_SET_GS)
3412
            idx = R_GS;
3413
        else
3414
            idx = R_FS;
3415
        cpu_x86_load_seg(env, idx, 0);
3416
        env->segs[idx].base = addr;
3417
        break;
3418
    case TARGET_ARCH_GET_GS:
3419
    case TARGET_ARCH_GET_FS:
3420
        if (code == TARGET_ARCH_GET_GS)
3421
            idx = R_GS;
3422
        else
3423
            idx = R_FS;
3424
        val = env->segs[idx].base;
3425
        if (put_user(val, addr, abi_ulong))
3426
            return -TARGET_EFAULT;
3427
        break;
3428
    default:
3429
        ret = -TARGET_EINVAL;
3430
        break;
3431
    }
3432
    return 0;
3433
}
3434
#endif
3435

    
3436
#endif /* defined(TARGET_I386) */
3437

    
3438
#if defined(USE_NPTL)
3439

    
3440
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3441

    
3442
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3443
typedef struct {
3444
    CPUState *env;
3445
    pthread_mutex_t mutex;
3446
    pthread_cond_t cond;
3447
    pthread_t thread;
3448
    uint32_t tid;
3449
    abi_ulong child_tidptr;
3450
    abi_ulong parent_tidptr;
3451
    sigset_t sigmask;
3452
} new_thread_info;
3453

    
3454
static void *clone_func(void *arg)
3455
{
3456
    new_thread_info *info = arg;
3457
    CPUState *env;
3458
    TaskState *ts;
3459

    
3460
    env = info->env;
3461
    thread_env = env;
3462
    ts = (TaskState *)thread_env->opaque;
3463
    info->tid = gettid();
3464
    env->host_tid = info->tid;
3465
    task_settid(ts);
3466
    if (info->child_tidptr)
3467
        put_user_u32(info->tid, info->child_tidptr);
3468
    if (info->parent_tidptr)
3469
        put_user_u32(info->tid, info->parent_tidptr);
3470
    /* Enable signals.  */
3471
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3472
    /* Signal to the parent that we're ready.  */
3473
    pthread_mutex_lock(&info->mutex);
3474
    pthread_cond_broadcast(&info->cond);
3475
    pthread_mutex_unlock(&info->mutex);
3476
    /* Wait until the parent has finshed initializing the tls state.  */
3477
    pthread_mutex_lock(&clone_lock);
3478
    pthread_mutex_unlock(&clone_lock);
3479
    cpu_loop(env);
3480
    /* never exits */
3481
    return NULL;
3482
}
3483
#else
3484
/* this stack is the equivalent of the kernel stack associated with a
3485
   thread/process */
3486
#define NEW_STACK_SIZE 8192
3487

    
3488
static int clone_func(void *arg)
3489
{
3490
    CPUState *env = arg;
3491
    cpu_loop(env);
3492
    /* never exits */
3493
    return 0;
3494
}
3495
#endif
3496

    
3497
/* do_fork() Must return host values and target errnos (unlike most
3498
   do_*() functions). */
3499
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3500
                   abi_ulong parent_tidptr, target_ulong newtls,
3501
                   abi_ulong child_tidptr)
3502
{
3503
    int ret;
3504
    TaskState *ts;
3505
    uint8_t *new_stack;
3506
    CPUState *new_env;
3507
#if defined(USE_NPTL)
3508
    unsigned int nptl_flags;
3509
    sigset_t sigmask;
3510
#endif
3511

    
3512
    /* Emulate vfork() with fork() */
3513
    if (flags & CLONE_VFORK)
3514
        flags &= ~(CLONE_VFORK | CLONE_VM);
3515

    
3516
    if (flags & CLONE_VM) {
3517
        TaskState *parent_ts = (TaskState *)env->opaque;
3518
#if defined(USE_NPTL)
3519
        new_thread_info info;
3520
        pthread_attr_t attr;
3521
#endif
3522
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3523
        init_task_state(ts);
3524
        new_stack = ts->stack;
3525
        /* we create a new CPU instance. */
3526
        new_env = cpu_copy(env);
3527
        /* Init regs that differ from the parent.  */
3528
        cpu_clone_regs(new_env, newsp);
3529
        new_env->opaque = ts;
3530
        ts->bprm = parent_ts->bprm;
3531
        ts->info = parent_ts->info;
3532
#if defined(USE_NPTL)
3533
        nptl_flags = flags;
3534
        flags &= ~CLONE_NPTL_FLAGS2;
3535

    
3536
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3537
            ts->child_tidptr = child_tidptr;
3538
        }
3539

    
3540
        if (nptl_flags & CLONE_SETTLS)
3541
            cpu_set_tls (new_env, newtls);
3542

    
3543
        /* Grab a mutex so that thread setup appears atomic.  */
3544
        pthread_mutex_lock(&clone_lock);
3545

    
3546
        memset(&info, 0, sizeof(info));
3547
        pthread_mutex_init(&info.mutex, NULL);
3548
        pthread_mutex_lock(&info.mutex);
3549
        pthread_cond_init(&info.cond, NULL);
3550
        info.env = new_env;
3551
        if (nptl_flags & CLONE_CHILD_SETTID)
3552
            info.child_tidptr = child_tidptr;
3553
        if (nptl_flags & CLONE_PARENT_SETTID)
3554
            info.parent_tidptr = parent_tidptr;
3555

    
3556
        ret = pthread_attr_init(&attr);
3557
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3558
        /* It is not safe to deliver signals until the child has finished
3559
           initializing, so temporarily block all signals.  */
3560
        sigfillset(&sigmask);
3561
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3562

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

    
3566
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3567
        pthread_attr_destroy(&attr);
3568
        if (ret == 0) {
3569
            /* Wait for the child to initialize.  */
3570
            pthread_cond_wait(&info.cond, &info.mutex);
3571
            ret = info.tid;
3572
            if (flags & CLONE_PARENT_SETTID)
3573
                put_user_u32(ret, parent_tidptr);
3574
        } else {
3575
            ret = -1;
3576
        }
3577
        pthread_mutex_unlock(&info.mutex);
3578
        pthread_cond_destroy(&info.cond);
3579
        pthread_mutex_destroy(&info.mutex);
3580
        pthread_mutex_unlock(&clone_lock);
3581
#else
3582
        if (flags & CLONE_NPTL_FLAGS2)
3583
            return -EINVAL;
3584
        /* This is probably going to die very quickly, but do it anyway.  */
3585
#ifdef __ia64__
3586
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3587
#else
3588
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3589
#endif
3590
#endif
3591
    } else {
3592
        /* if no CLONE_VM, we consider it is a fork */
3593
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3594
            return -EINVAL;
3595
        fork_start();
3596
        ret = fork();
3597
        if (ret == 0) {
3598
            /* Child Process.  */
3599
            cpu_clone_regs(env, newsp);
3600
            fork_end(1);
3601
#if defined(USE_NPTL)
3602
            /* There is a race condition here.  The parent process could
3603
               theoretically read the TID in the child process before the child
3604
               tid is set.  This would require using either ptrace
3605
               (not implemented) or having *_tidptr to point at a shared memory
3606
               mapping.  We can't repeat the spinlock hack used above because
3607
               the child process gets its own copy of the lock.  */
3608
            if (flags & CLONE_CHILD_SETTID)
3609
                put_user_u32(gettid(), child_tidptr);
3610
            if (flags & CLONE_PARENT_SETTID)
3611
                put_user_u32(gettid(), parent_tidptr);
3612
            ts = (TaskState *)env->opaque;
3613
            if (flags & CLONE_SETTLS)
3614
                cpu_set_tls (env, newtls);
3615
            if (flags & CLONE_CHILD_CLEARTID)
3616
                ts->child_tidptr = child_tidptr;
3617
#endif
3618
        } else {
3619
            fork_end(0);
3620
        }
3621
    }
3622
    return ret;
3623
}
3624

    
3625
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3626
{
3627
    struct flock fl;
3628
    struct target_flock *target_fl;
3629
    struct flock64 fl64;
3630
    struct target_flock64 *target_fl64;
3631
    abi_long ret;
3632

    
3633
    switch(cmd) {
3634
    case TARGET_F_GETLK:
3635
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3636
            return -TARGET_EFAULT;
3637
        fl.l_type = tswap16(target_fl->l_type);
3638
        fl.l_whence = tswap16(target_fl->l_whence);
3639
        fl.l_start = tswapl(target_fl->l_start);
3640
        fl.l_len = tswapl(target_fl->l_len);
3641
        fl.l_pid = tswapl(target_fl->l_pid);
3642
        unlock_user_struct(target_fl, arg, 0);
3643
        ret = get_errno(fcntl(fd, cmd, &fl));
3644
        if (ret == 0) {
3645
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3646
                return -TARGET_EFAULT;
3647
            target_fl->l_type = tswap16(fl.l_type);
3648
            target_fl->l_whence = tswap16(fl.l_whence);
3649
            target_fl->l_start = tswapl(fl.l_start);
3650
            target_fl->l_len = tswapl(fl.l_len);
3651
            target_fl->l_pid = tswapl(fl.l_pid);
3652
            unlock_user_struct(target_fl, arg, 1);
3653
        }
3654
        break;
3655

    
3656
    case TARGET_F_SETLK:
3657
    case TARGET_F_SETLKW:
3658
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3659
            return -TARGET_EFAULT;
3660
        fl.l_type = tswap16(target_fl->l_type);
3661
        fl.l_whence = tswap16(target_fl->l_whence);
3662
        fl.l_start = tswapl(target_fl->l_start);
3663
        fl.l_len = tswapl(target_fl->l_len);
3664
        fl.l_pid = tswapl(target_fl->l_pid);
3665
        unlock_user_struct(target_fl, arg, 0);
3666
        ret = get_errno(fcntl(fd, cmd, &fl));
3667
        break;
3668

    
3669
    case TARGET_F_GETLK64:
3670
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3671
            return -TARGET_EFAULT;
3672
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3673
        fl64.l_whence = tswap16(target_fl64->l_whence);
3674
        fl64.l_start = tswapl(target_fl64->l_start);
3675
        fl64.l_len = tswapl(target_fl64->l_len);
3676
        fl64.l_pid = tswap16(target_fl64->l_pid);
3677
        unlock_user_struct(target_fl64, arg, 0);
3678
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3679
        if (ret == 0) {
3680
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3681
                return -TARGET_EFAULT;
3682
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3683
            target_fl64->l_whence = tswap16(fl64.l_whence);
3684
            target_fl64->l_start = tswapl(fl64.l_start);
3685
            target_fl64->l_len = tswapl(fl64.l_len);
3686
            target_fl64->l_pid = tswapl(fl64.l_pid);
3687
            unlock_user_struct(target_fl64, arg, 1);
3688
        }
3689
        break;
3690
    case TARGET_F_SETLK64:
3691
    case TARGET_F_SETLKW64:
3692
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3693
            return -TARGET_EFAULT;
3694
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3695
        fl64.l_whence = tswap16(target_fl64->l_whence);
3696
        fl64.l_start = tswapl(target_fl64->l_start);
3697
        fl64.l_len = tswapl(target_fl64->l_len);
3698
        fl64.l_pid = tswap16(target_fl64->l_pid);
3699
        unlock_user_struct(target_fl64, arg, 0);
3700
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3701
        break;
3702

    
3703
    case F_GETFL:
3704
        ret = get_errno(fcntl(fd, cmd, arg));
3705
        if (ret >= 0) {
3706
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3707
        }
3708
        break;
3709

    
3710
    case F_SETFL:
3711
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3712
        break;
3713

    
3714
    default:
3715
        ret = get_errno(fcntl(fd, cmd, arg));
3716
        break;
3717
    }
3718
    return ret;
3719
}
3720

    
3721
#ifdef USE_UID16
3722

    
3723
static inline int high2lowuid(int uid)
3724
{
3725
    if (uid > 65535)
3726
        return 65534;
3727
    else
3728
        return uid;
3729
}
3730

    
3731
static inline int high2lowgid(int gid)
3732
{
3733
    if (gid > 65535)
3734
        return 65534;
3735
    else
3736
        return gid;
3737
}
3738

    
3739
static inline int low2highuid(int uid)
3740
{
3741
    if ((int16_t)uid == -1)
3742
        return -1;
3743
    else
3744
        return uid;
3745
}
3746

    
3747
static inline int low2highgid(int gid)
3748
{
3749
    if ((int16_t)gid == -1)
3750
        return -1;
3751
    else
3752
        return gid;
3753
}
3754

    
3755
#endif /* USE_UID16 */
3756

    
3757
void syscall_init(void)
3758
{
3759
    IOCTLEntry *ie;
3760
    const argtype *arg_type;
3761
    int size;
3762
    int i;
3763

    
3764
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3765
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3766
#include "syscall_types.h"
3767
#undef STRUCT
3768
#undef STRUCT_SPECIAL
3769

    
3770
    /* we patch the ioctl size if necessary. We rely on the fact that
3771
       no ioctl has all the bits at '1' in the size field */
3772
    ie = ioctl_entries;
3773
    while (ie->target_cmd != 0) {
3774
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3775
            TARGET_IOC_SIZEMASK) {
3776
            arg_type = ie->arg_type;
3777
            if (arg_type[0] != TYPE_PTR) {
3778
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3779
                        ie->target_cmd);
3780
                exit(1);
3781
            }
3782
            arg_type++;
3783
            size = thunk_type_size(arg_type, 0);
3784
            ie->target_cmd = (ie->target_cmd &
3785
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3786
                (size << TARGET_IOC_SIZESHIFT);
3787
        }
3788

    
3789
        /* Build target_to_host_errno_table[] table from
3790
         * host_to_target_errno_table[]. */
3791
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3792
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3793

    
3794
        /* automatic consistency check if same arch */
3795
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3796
    (defined(__x86_64__) && defined(TARGET_X86_64))
3797
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3798
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3799
                    ie->name, ie->target_cmd, ie->host_cmd);
3800
        }
3801
#endif
3802
        ie++;
3803
    }
3804
}
3805

    
3806
#if TARGET_ABI_BITS == 32
3807
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3808
{
3809
#ifdef TARGET_WORDS_BIGENDIAN
3810
    return ((uint64_t)word0 << 32) | word1;
3811
#else
3812
    return ((uint64_t)word1 << 32) | word0;
3813
#endif
3814
}
3815
#else /* TARGET_ABI_BITS == 32 */
3816
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3817
{
3818
    return word0;
3819
}
3820
#endif /* TARGET_ABI_BITS != 32 */
3821

    
3822
#ifdef TARGET_NR_truncate64
3823
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3824
                                         abi_long arg2,
3825
                                         abi_long arg3,
3826
                                         abi_long arg4)
3827
{
3828
#ifdef TARGET_ARM
3829
    if (((CPUARMState *)cpu_env)->eabi)
3830
      {
3831
        arg2 = arg3;
3832
        arg3 = arg4;
3833
      }
3834
#endif
3835
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3836
}
3837
#endif
3838

    
3839
#ifdef TARGET_NR_ftruncate64
3840
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3841
                                          abi_long arg2,
3842
                                          abi_long arg3,
3843
                                          abi_long arg4)
3844
{
3845
#ifdef TARGET_ARM
3846
    if (((CPUARMState *)cpu_env)->eabi)
3847
      {
3848
        arg2 = arg3;
3849
        arg3 = arg4;
3850
      }
3851
#endif
3852
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3853
}
3854
#endif
3855

    
3856
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3857
                                               abi_ulong target_addr)
3858
{
3859
    struct target_timespec *target_ts;
3860

    
3861
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3862
        return -TARGET_EFAULT;
3863
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3864
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3865
    unlock_user_struct(target_ts, target_addr, 0);
3866
    return 0;
3867
}
3868

    
3869
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3870
                                               struct timespec *host_ts)
3871
{
3872
    struct target_timespec *target_ts;
3873

    
3874
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3875
        return -TARGET_EFAULT;
3876
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3877
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3878
    unlock_user_struct(target_ts, target_addr, 1);
3879
    return 0;
3880
}
3881

    
3882
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3883
static inline abi_long host_to_target_stat64(void *cpu_env,
3884
                                             abi_ulong target_addr,
3885
                                             struct stat *host_st)
3886
{
3887
#ifdef TARGET_ARM
3888
    if (((CPUARMState *)cpu_env)->eabi) {
3889
        struct target_eabi_stat64 *target_st;
3890

    
3891
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3892
            return -TARGET_EFAULT;
3893
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3894
        __put_user(host_st->st_dev, &target_st->st_dev);
3895
        __put_user(host_st->st_ino, &target_st->st_ino);
3896
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3897
        __put_user(host_st->st_ino, &target_st->__st_ino);
3898
#endif
3899
        __put_user(host_st->st_mode, &target_st->st_mode);
3900
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3901
        __put_user(host_st->st_uid, &target_st->st_uid);
3902
        __put_user(host_st->st_gid, &target_st->st_gid);
3903
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3904
        __put_user(host_st->st_size, &target_st->st_size);
3905
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3906
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3907
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3908
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3909
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3910
        unlock_user_struct(target_st, target_addr, 1);
3911
    } else
3912
#endif
3913
    {
3914
#if TARGET_LONG_BITS == 64
3915
        struct target_stat *target_st;
3916
#else
3917
        struct target_stat64 *target_st;
3918
#endif
3919

    
3920
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3921
            return -TARGET_EFAULT;
3922
        memset(target_st, 0, sizeof(*target_st));
3923
        __put_user(host_st->st_dev, &target_st->st_dev);
3924
        __put_user(host_st->st_ino, &target_st->st_ino);
3925
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3926
        __put_user(host_st->st_ino, &target_st->__st_ino);
3927
#endif
3928
        __put_user(host_st->st_mode, &target_st->st_mode);
3929
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3930
        __put_user(host_st->st_uid, &target_st->st_uid);
3931
        __put_user(host_st->st_gid, &target_st->st_gid);
3932
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3933
        /* XXX: better use of kernel struct */
3934
        __put_user(host_st->st_size, &target_st->st_size);
3935
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3936
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3937
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3938
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3939
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3940
        unlock_user_struct(target_st, target_addr, 1);
3941
    }
3942

    
3943
    return 0;
3944
}
3945
#endif
3946

    
3947
#if defined(USE_NPTL)
3948
/* ??? Using host futex calls even when target atomic operations
3949
   are not really atomic probably breaks things.  However implementing
3950
   futexes locally would make futexes shared between multiple processes
3951
   tricky.  However they're probably useless because guest atomic
3952
   operations won't work either.  */
3953
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3954
                    target_ulong uaddr2, int val3)
3955
{
3956
    struct timespec ts, *pts;
3957

    
3958
    /* ??? We assume FUTEX_* constants are the same on both host
3959
       and target.  */
3960
#ifdef FUTEX_CMD_MASK
3961
    switch ((op&FUTEX_CMD_MASK)) {
3962
#else
3963
    switch (op) {
3964
#endif
3965
    case FUTEX_WAIT:
3966
        if (timeout) {
3967
            pts = &ts;
3968
            target_to_host_timespec(pts, timeout);
3969
        } else {
3970
            pts = NULL;
3971
        }
3972
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
3973
                         pts, NULL, 0));
3974
    case FUTEX_WAKE:
3975
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
3976
    case FUTEX_WAKE_OP:
3977
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, g2h(uaddr2), val3 ));
3978
    case FUTEX_FD:
3979
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
3980
    case FUTEX_REQUEUE:
3981
        return get_errno(sys_futex(g2h(uaddr), op, val,
3982
                         NULL, g2h(uaddr2), 0));
3983
    case FUTEX_CMP_REQUEUE:
3984
        return get_errno(sys_futex(g2h(uaddr), op, val,
3985
                         NULL, g2h(uaddr2), tswap32(val3)));
3986
    default:
3987
        return -TARGET_ENOSYS;
3988
    }
3989
}
3990
#endif
3991

    
3992
/* Map host to target signal numbers for the wait family of syscalls.
3993
   Assume all other status bits are the same.  */
3994
static int host_to_target_waitstatus(int status)
3995
{
3996
    if (WIFSIGNALED(status)) {
3997
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
3998
    }
3999
    if (WIFSTOPPED(status)) {
4000
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4001
               | (status & 0xff);
4002
    }
4003
    return status;
4004
}
4005

    
4006
int get_osversion(void)
4007
{
4008
    static int osversion;
4009
    struct new_utsname buf;
4010
    const char *s;
4011
    int i, n, tmp;
4012
    if (osversion)
4013
        return osversion;
4014
    if (qemu_uname_release && *qemu_uname_release) {
4015
        s = qemu_uname_release;
4016
    } else {
4017
        if (sys_uname(&buf))
4018
            return 0;
4019
        s = buf.release;
4020
    }
4021
    tmp = 0;
4022
    for (i = 0; i < 3; i++) {
4023
        n = 0;
4024
        while (*s >= '0' && *s <= '9') {
4025
            n *= 10;
4026
            n += *s - '0';
4027
            s++;
4028
        }
4029
        tmp = (tmp << 8) + n;
4030
        if (*s == '.')
4031
            s++;
4032
    }
4033
    osversion = tmp;
4034
    return osversion;
4035
}
4036

    
4037
/* do_syscall() should always have a single exit point at the end so
4038
   that actions, such as logging of syscall results, can be performed.
4039
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4040
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4041
                    abi_long arg2, abi_long arg3, abi_long arg4,
4042
                    abi_long arg5, abi_long arg6)
4043
{
4044
    abi_long ret;
4045
    struct stat st;
4046
    struct statfs stfs;
4047
    void *p;
4048

    
4049
#ifdef DEBUG
4050
    gemu_log("syscall %d", num);
4051
#endif
4052
    if(do_strace)
4053
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4054

    
4055
    switch(num) {
4056
    case TARGET_NR_exit:
4057
#ifdef USE_NPTL
4058
      /* In old applications this may be used to implement _exit(2).
4059
         However in threaded applictions it is used for thread termination,
4060
         and _exit_group is used for application termination.
4061
         Do thread termination if we have more then one thread.  */
4062
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4063
         be disabling signals.  */
4064
      if (first_cpu->next_cpu) {
4065
          TaskState *ts;
4066
          CPUState **lastp;
4067
          CPUState *p;
4068

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

    
4232
            argc = 0;
4233
            guest_argp = arg2;
4234
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4235
                if (get_user_ual(addr, gp))
4236
                    goto efault;
4237
                if (!addr)
4238
                    break;
4239
                argc++;
4240
            }
4241
            envc = 0;
4242
            guest_envp = arg3;
4243
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4244
                if (get_user_ual(addr, gp))
4245
                    goto efault;
4246
                if (!addr)
4247
                    break;
4248
                envc++;
4249
            }
4250

    
4251
            argp = alloca((argc + 1) * sizeof(void *));
4252
            envp = alloca((envc + 1) * sizeof(void *));
4253

    
4254
            for (gp = guest_argp, q = argp; gp;
4255
                  gp += sizeof(abi_ulong), q++) {
4256
                if (get_user_ual(addr, gp))
4257
                    goto execve_efault;
4258
                if (!addr)
4259
                    break;
4260
                if (!(*q = lock_user_string(addr)))
4261
                    goto execve_efault;
4262
            }
4263
            *q = NULL;
4264

    
4265
            for (gp = guest_envp, q = envp; gp;
4266
                  gp += sizeof(abi_ulong), q++) {
4267
                if (get_user_ual(addr, gp))
4268
                    goto execve_efault;
4269
                if (!addr)
4270
                    break;
4271
                if (!(*q = lock_user_string(addr)))
4272
                    goto execve_efault;
4273
            }
4274
            *q = NULL;
4275

    
4276
            if (!(p = lock_user_string(arg1)))
4277
                goto execve_efault;
4278
            ret = get_errno(execve(p, argp, envp));
4279
            unlock_user(p, arg1, 0);
4280

    
4281
            goto execve_end;
4282

    
4283
        execve_efault:
4284
            ret = -TARGET_EFAULT;
4285

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

    
4695
            if (arg2) {
4696
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4697
                    goto efault;
4698
                act._sa_handler = old_act->_sa_handler;
4699
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4700
                act.sa_flags = old_act->sa_flags;
4701
                unlock_user_struct(old_act, arg2, 0);
4702
                pact = &act;
4703
            } else {
4704
                pact = NULL;
4705
            }
4706

    
4707
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4708

    
4709
            if (!is_error(ret) && arg3) {
4710
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4711
                    goto efault;
4712
                old_act->_sa_handler = oact._sa_handler;
4713
                old_act->sa_flags = oact.sa_flags;
4714
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4715
                old_act->sa_mask.sig[1] = 0;
4716
                old_act->sa_mask.sig[2] = 0;
4717
                old_act->sa_mask.sig[3] = 0;
4718
                unlock_user_struct(old_act, arg3, 1);
4719
            }
4720
#endif
4721
        }
4722
        break;
4723
#endif
4724
    case TARGET_NR_rt_sigaction:
4725
        {
4726
            struct target_sigaction *act;
4727
            struct target_sigaction *oact;
4728

    
4729
            if (arg2) {
4730
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4731
                    goto efault;
4732
            } else
4733
                act = NULL;
4734
            if (arg3) {
4735
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4736
                    ret = -TARGET_EFAULT;
4737
                    goto rt_sigaction_fail;
4738
                }
4739
            } else
4740
                oact = NULL;
4741
            ret = get_errno(do_sigaction(arg1, act, oact));
4742
        rt_sigaction_fail:
4743
            if (act)
4744
                unlock_user_struct(act, arg2, 0);
4745
            if (oact)
4746
                unlock_user_struct(oact, arg3, 1);
4747
        }
4748
        break;
4749
#ifdef TARGET_NR_sgetmask /* not on alpha */
4750
    case TARGET_NR_sgetmask:
4751
        {
4752
            sigset_t cur_set;
4753
            abi_ulong target_set;
4754
            sigprocmask(0, NULL, &cur_set);
4755
            host_to_target_old_sigset(&target_set, &cur_set);
4756
            ret = target_set;
4757
        }
4758
        break;
4759
#endif
4760
#ifdef TARGET_NR_ssetmask /* not on alpha */
4761
    case TARGET_NR_ssetmask:
4762
        {
4763
            sigset_t set, oset, cur_set;
4764
            abi_ulong target_set = arg1;
4765
            sigprocmask(0, NULL, &cur_set);
4766
            target_to_host_old_sigset(&set, &target_set);
4767
            sigorset(&set, &set, &cur_set);
4768
            sigprocmask(SIG_SETMASK, &set, &oset);
4769
            host_to_target_old_sigset(&target_set, &oset);
4770
            ret = target_set;
4771
        }
4772
        break;
4773
#endif
4774
#ifdef TARGET_NR_sigprocmask
4775
    case TARGET_NR_sigprocmask:
4776
        {
4777
            int how = arg1;
4778
            sigset_t set, oldset, *set_ptr;
4779

    
4780
            if (arg2) {
4781
                switch(how) {
4782
                case TARGET_SIG_BLOCK:
4783
                    how = SIG_BLOCK;
4784
                    break;
4785
                case TARGET_SIG_UNBLOCK:
4786
                    how = SIG_UNBLOCK;
4787
                    break;
4788
                case TARGET_SIG_SETMASK:
4789
                    how = SIG_SETMASK;
4790
                    break;
4791
                default:
4792
                    ret = -TARGET_EINVAL;
4793
                    goto fail;
4794
                }
4795
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4796
                    goto efault;
4797
                target_to_host_old_sigset(&set, p);
4798
                unlock_user(p, arg2, 0);
4799
                set_ptr = &set;
4800
            } else {
4801
                how = 0;
4802
                set_ptr = NULL;
4803
            }
4804
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4805
            if (!is_error(ret) && arg3) {
4806
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4807
                    goto efault;
4808
                host_to_target_old_sigset(p, &oldset);
4809
                unlock_user(p, arg3, sizeof(target_sigset_t));
4810
            }
4811
        }
4812
        break;
4813
#endif
4814
    case TARGET_NR_rt_sigprocmask:
4815
        {
4816
            int how = arg1;
4817
            sigset_t set, oldset, *set_ptr;
4818

    
4819
            if (arg2) {
4820
                switch(how) {
4821
                case TARGET_SIG_BLOCK:
4822
                    how = SIG_BLOCK;
4823
                    break;
4824
                case TARGET_SIG_UNBLOCK:
4825
                    how = SIG_UNBLOCK;
4826
                    break;
4827
                case TARGET_SIG_SETMASK:
4828
                    how = SIG_SETMASK;
4829
                    break;
4830
                default:
4831
                    ret = -TARGET_EINVAL;
4832
                    goto fail;
4833
                }
4834
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4835
                    goto efault;
4836
                target_to_host_sigset(&set, p);
4837
                unlock_user(p, arg2, 0);
4838
                set_ptr = &set;
4839
            } else {
4840
                how = 0;
4841
                set_ptr = NULL;
4842
            }
4843
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4844
            if (!is_error(ret) && arg3) {
4845
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4846
                    goto efault;
4847
                host_to_target_sigset(p, &oldset);
4848
                unlock_user(p, arg3, sizeof(target_sigset_t));
4849
            }
4850
        }
4851
        break;
4852
#ifdef TARGET_NR_sigpending
4853
    case TARGET_NR_sigpending:
4854
        {
4855
            sigset_t set;
4856
            ret = get_errno(sigpending(&set));
4857
            if (!is_error(ret)) {
4858
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4859
                    goto efault;
4860
                host_to_target_old_sigset(p, &set);
4861
                unlock_user(p, arg1, sizeof(target_sigset_t));
4862
            }
4863
        }
4864
        break;
4865
#endif
4866
    case TARGET_NR_rt_sigpending:
4867
        {
4868
            sigset_t set;
4869
            ret = get_errno(sigpending(&set));
4870
            if (!is_error(ret)) {
4871
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4872
                    goto efault;
4873
                host_to_target_sigset(p, &set);
4874
                unlock_user(p, arg1, sizeof(target_sigset_t));
4875
            }
4876
        }
4877
        break;
4878
#ifdef TARGET_NR_sigsuspend
4879
    case TARGET_NR_sigsuspend:
4880
        {
4881
            sigset_t set;
4882
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4883
                goto efault;
4884
            target_to_host_old_sigset(&set, p);
4885
            unlock_user(p, arg1, 0);
4886
            ret = get_errno(sigsuspend(&set));
4887
        }
4888
        break;
4889
#endif
4890
    case TARGET_NR_rt_sigsuspend:
4891
        {
4892
            sigset_t set;
4893
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4894
                goto efault;
4895
            target_to_host_sigset(&set, p);
4896
            unlock_user(p, arg1, 0);
4897
            ret = get_errno(sigsuspend(&set));
4898
        }
4899
        break;
4900
    case TARGET_NR_rt_sigtimedwait:
4901
        {
4902
            sigset_t set;
4903
            struct timespec uts, *puts;
4904
            siginfo_t uinfo;
4905

    
4906
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4907
                goto efault;
4908
            target_to_host_sigset(&set, p);
4909
            unlock_user(p, arg1, 0);
4910
            if (arg3) {
4911
                puts = &uts;
4912
                target_to_host_timespec(puts, arg3);
4913
            } else {
4914
                puts = NULL;
4915
            }
4916
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4917
            if (!is_error(ret) && arg2) {
4918
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4919
                    goto efault;
4920
                host_to_target_siginfo(p, &uinfo);
4921
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4922
            }
4923
        }
4924
        break;
4925
    case TARGET_NR_rt_sigqueueinfo:
4926
        {
4927
            siginfo_t uinfo;
4928
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4929
                goto efault;
4930
            target_to_host_siginfo(&uinfo, p);
4931
            unlock_user(p, arg1, 0);
4932
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4933
        }
4934
        break;
4935
#ifdef TARGET_NR_sigreturn
4936
    case TARGET_NR_sigreturn:
4937
        /* NOTE: ret is eax, so not transcoding must be done */
4938
        ret = do_sigreturn(cpu_env);
4939
        break;
4940
#endif
4941
    case TARGET_NR_rt_sigreturn:
4942
        /* NOTE: ret is eax, so not transcoding must be done */
4943
        ret = do_rt_sigreturn(cpu_env);
4944
        break;
4945
    case TARGET_NR_sethostname:
4946
        if (!(p = lock_user_string(arg1)))
4947
            goto efault;
4948
        ret = get_errno(sethostname(p, arg2));
4949
        unlock_user(p, arg1, 0);
4950
        break;
4951
    case TARGET_NR_setrlimit:
4952
        {
4953
            /* XXX: convert resource ? */
4954
            int resource = arg1;
4955
            struct target_rlimit *target_rlim;
4956
            struct rlimit rlim;
4957
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4958
                goto efault;
4959
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4960
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4961
            unlock_user_struct(target_rlim, arg2, 0);
4962
            ret = get_errno(setrlimit(resource, &rlim));
4963
        }
4964
        break;
4965
    case TARGET_NR_getrlimit:
4966
        {
4967
            /* XXX: convert resource ? */
4968
            int resource = arg1;
4969
            struct target_rlimit *target_rlim;
4970
            struct rlimit rlim;
4971

    
4972
            ret = get_errno(getrlimit(resource, &rlim));
4973
            if (!is_error(ret)) {
4974
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4975
                    goto efault;
4976
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4977
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4978
                unlock_user_struct(target_rlim, arg2, 1);
4979
            }
4980
        }
4981
        break;
4982
    case TARGET_NR_getrusage:
4983
        {
4984
            struct rusage rusage;
4985
            ret = get_errno(getrusage(arg1, &rusage));
4986
            if (!is_error(ret)) {
4987
                host_to_target_rusage(arg2, &rusage);
4988
            }
4989
        }
4990
        break;
4991
    case TARGET_NR_gettimeofday:
4992
        {
4993
            struct timeval tv;
4994
            ret = get_errno(gettimeofday(&tv, NULL));
4995
            if (!is_error(ret)) {
4996
                if (copy_to_user_timeval(arg1, &tv))
4997
                    goto efault;
4998
            }
4999
        }
5000
        break;
5001
    case TARGET_NR_settimeofday:
5002
        {
5003
            struct timeval tv;
5004
            if (copy_from_user_timeval(&tv, arg1))
5005
                goto efault;
5006
            ret = get_errno(settimeofday(&tv, NULL));
5007
        }
5008
        break;
5009
#ifdef TARGET_NR_select
5010
    case TARGET_NR_select:
5011
        {
5012
            struct target_sel_arg_struct *sel;
5013
            abi_ulong inp, outp, exp, tvp;
5014
            long nsel;
5015

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

    
5231
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5232
                goto efault;
5233
            __put_user(stfs.f_type, &target_stfs->f_type);
5234
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5235
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5236
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5237
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5238
            __put_user(stfs.f_files, &target_stfs->f_files);
5239
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5240
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5241
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5242
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5243
            unlock_user_struct(target_stfs, arg2, 1);
5244
        }
5245
        break;
5246
    case TARGET_NR_fstatfs:
5247
        ret = get_errno(fstatfs(arg1, &stfs));
5248
        goto convert_statfs;
5249
#ifdef TARGET_NR_statfs64
5250
    case TARGET_NR_statfs64:
5251
        if (!(p = lock_user_string(arg1)))
5252
            goto efault;
5253
        ret = get_errno(statfs(path(p), &stfs));
5254
        unlock_user(p, arg1, 0);
5255
    convert_statfs64:
5256
        if (!is_error(ret)) {
5257
            struct target_statfs64 *target_stfs;
5258

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

    
5373
    case TARGET_NR_syslog:
5374
        if (!(p = lock_user_string(arg2)))
5375
            goto efault;
5376
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5377
        unlock_user(p, arg2, 0);
5378
        break;
5379

    
5380
    case TARGET_NR_setitimer:
5381
        {
5382
            struct itimerval value, ovalue, *pvalue;
5383

    
5384
            if (arg2) {
5385
                pvalue = &value;
5386
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5387
                    || copy_from_user_timeval(&pvalue->it_value,
5388
                                              arg2 + sizeof(struct target_timeval)))
5389
                    goto efault;
5390
            } else {
5391
                pvalue = NULL;
5392
            }
5393
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5394
            if (!is_error(ret) && arg3) {
5395
                if (copy_to_user_timeval(arg3,
5396
                                         &ovalue.it_interval)
5397
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5398
                                            &ovalue.it_value))
5399
                    goto efault;
5400
            }
5401
        }
5402
        break;
5403
    case TARGET_NR_getitimer:
5404
        {
5405
            struct itimerval value;
5406

    
5407
            ret = get_errno(getitimer(arg1, &value));
5408
            if (!is_error(ret) && arg2) {
5409
                if (copy_to_user_timeval(arg2,
5410
                                         &value.it_interval)
5411
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5412
                                            &value.it_value))
5413
                    goto efault;
5414
            }
5415
        }
5416
        break;
5417
    case TARGET_NR_stat:
5418
        if (!(p = lock_user_string(arg1)))
5419
            goto efault;
5420
        ret = get_errno(stat(path(p), &st));
5421
        unlock_user(p, arg1, 0);
5422
        goto do_stat;
5423
    case TARGET_NR_lstat:
5424
        if (!(p = lock_user_string(arg1)))
5425
            goto efault;
5426
        ret = get_errno(lstat(path(p), &st));
5427
        unlock_user(p, arg1, 0);
5428
        goto do_stat;
5429
    case TARGET_NR_fstat:
5430
        {
5431
            ret = get_errno(fstat(arg1, &st));
5432
        do_stat:
5433
            if (!is_error(ret)) {
5434
                struct target_stat *target_st;
5435

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

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

    
5710
            dirp = malloc(count);
5711
            if (!dirp) {
5712
                ret = -TARGET_ENOMEM;
5713
                goto fail;
5714
            }
5715

    
5716
            ret = get_errno(sys_getdents(arg1, dirp, count));
5717
            if (!is_error(ret)) {
5718
                struct linux_dirent *de;
5719
                struct target_dirent *tde;
5720
                int len = ret;
5721
                int reclen, treclen;
5722
                int count1, tnamelen;
5723

    
5724
                count1 = 0;
5725
                de = dirp;
5726
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5727
                    goto efault;
5728
                tde = target_dirp;
5729
                while (len > 0) {
5730
                    reclen = de->d_reclen;
5731
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5732
                    tde->d_reclen = tswap16(treclen);
5733
                    tde->d_ino = tswapl(de->d_ino);
5734
                    tde->d_off = tswapl(de->d_off);
5735
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5736
                    if (tnamelen > 256)
5737
                        tnamelen = 256;
5738
                    /* XXX: may not be correct */
5739
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5740
                    de = (struct linux_dirent *)((char *)de + reclen);
5741
                    len -= reclen;
5742
                    tde = (struct target_dirent *)((char *)tde + treclen);
5743
                    count1 += treclen;
5744
                }
5745
                ret = count1;
5746
                unlock_user(target_dirp, arg2, ret);
5747
            }
5748
            free(dirp);
5749
        }
5750
#else
5751
        {
5752
            struct linux_dirent *dirp;
5753
            abi_long count = arg3;
5754

    
5755
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5756
                goto efault;
5757
            ret = get_errno(sys_getdents(arg1, dirp, count));
5758
            if (!is_error(ret)) {
5759
                struct linux_dirent *de;
5760
                int len = ret;
5761
                int reclen;
5762
                de = dirp;
5763
                while (len > 0) {
5764
                    reclen = de->d_reclen;
5765
                    if (reclen > len)
5766
                        break;
5767
                    de->d_reclen = tswap16(reclen);
5768
                    tswapls(&de->d_ino);
5769
                    tswapls(&de->d_off);
5770
                    de = (struct linux_dirent *)((char *)de + reclen);
5771
                    len -= reclen;
5772
                }
5773
            }
5774
            unlock_user(dirp, arg2, ret);
5775
        }
5776
#endif
5777
        break;
5778
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5779
    case TARGET_NR_getdents64:
5780
        {
5781
            struct linux_dirent64 *dirp;
5782
            abi_long count = arg3;
5783
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5784
                goto efault;
5785
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5786
            if (!is_error(ret)) {
5787
                struct linux_dirent64 *de;
5788
                int len = ret;
5789
                int reclen;
5790
                de = dirp;
5791
                while (len > 0) {
5792
                    reclen = de->d_reclen;
5793
                    if (reclen > len)
5794
                        break;
5795
                    de->d_reclen = tswap16(reclen);
5796
                    tswap64s((uint64_t *)&de->d_ino);
5797
                    tswap64s((uint64_t *)&de->d_off);
5798
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5799
                    len -= reclen;
5800
                }
5801
            }
5802
            unlock_user(dirp, arg2, ret);
5803
        }
5804
        break;
5805
#endif /* TARGET_NR_getdents64 */
5806
#ifdef TARGET_NR__newselect
5807
    case TARGET_NR__newselect:
5808
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5809
        break;
5810
#endif
5811
#ifdef TARGET_NR_poll
5812
    case TARGET_NR_poll:
5813
        {
5814
            struct target_pollfd *target_pfd;
5815
            unsigned int nfds = arg2;
5816
            int timeout = arg3;
5817
            struct pollfd *pfd;
5818
            unsigned int i;
5819

    
5820
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5821
            if (!target_pfd)
5822
                goto efault;
5823
            pfd = alloca(sizeof(struct pollfd) * nfds);
5824
            for(i = 0; i < nfds; i++) {
5825
                pfd[i].fd = tswap32(target_pfd[i].fd);
5826
                pfd[i].events = tswap16(target_pfd[i].events);
5827
            }
5828
            ret = get_errno(poll(pfd, nfds, timeout));
5829
            if (!is_error(ret)) {
5830
                for(i = 0; i < nfds; i++) {
5831
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5832
                }
5833
                ret += nfds * (sizeof(struct target_pollfd)
5834
                               - sizeof(struct pollfd));
5835
            }
5836
            unlock_user(target_pfd, arg1, ret);
5837
        }
5838
        break;
5839
#endif
5840
    case TARGET_NR_flock:
5841
        /* NOTE: the flock constant seems to be the same for every
5842
           Linux platform */
5843
        ret = get_errno(flock(arg1, arg2));
5844
        break;
5845
    case TARGET_NR_readv:
5846
        {
5847
            int count = arg3;
5848
            struct iovec *vec;
5849

    
5850
            vec = alloca(count * sizeof(struct iovec));
5851
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5852
                goto efault;
5853
            ret = get_errno(readv(arg1, vec, count));
5854
            unlock_iovec(vec, arg2, count, 1);
5855
        }
5856
        break;
5857
    case TARGET_NR_writev:
5858
        {
5859
            int count = arg3;
5860
            struct iovec *vec;
5861

    
5862
            vec = alloca(count * sizeof(struct iovec));
5863
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5864
                goto efault;
5865
            ret = get_errno(writev(arg1, vec, count));
5866
            unlock_iovec(vec, arg2, count, 0);
5867
        }
5868
        break;
5869
    case TARGET_NR_getsid:
5870
        ret = get_errno(getsid(arg1));
5871
        break;
5872
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5873
    case TARGET_NR_fdatasync:
5874
        ret = get_errno(fdatasync(arg1));
5875
        break;
5876
#endif
5877
    case TARGET_NR__sysctl:
5878
        /* We don't implement this, but ENOTDIR is always a safe
5879
           return value. */
5880
        ret = -TARGET_ENOTDIR;
5881
        break;
5882
    case TARGET_NR_sched_setparam:
5883
        {
5884
            struct sched_param *target_schp;
5885
            struct sched_param schp;
5886

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

    
6160
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6161
            ret = get_errno(getgroups(gidsetsize, grouplist));
6162
            if (gidsetsize == 0)
6163
                break;
6164
            if (!is_error(ret)) {
6165
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6166
                if (!target_grouplist)
6167
                    goto efault;
6168
                for(i = 0;i < ret; i++)
6169
                    target_grouplist[i] = tswap16(grouplist[i]);
6170
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6171
            }
6172
        }
6173
        break;
6174
    case TARGET_NR_setgroups:
6175
        {
6176
            int gidsetsize = arg1;
6177
            uint16_t *target_grouplist;
6178
            gid_t *grouplist;
6179
            int i;
6180

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

    
6266
#ifdef TARGET_NR_lchown32
6267
    case TARGET_NR_lchown32:
6268
        if (!(p = lock_user_string(arg1)))
6269
            goto efault;
6270
        ret = get_errno(lchown(p, arg2, arg3));
6271
        unlock_user(p, arg1, 0);
6272
        break;
6273
#endif
6274
#ifdef TARGET_NR_getuid32
6275
    case TARGET_NR_getuid32:
6276
        ret = get_errno(getuid());
6277
        break;
6278
#endif
6279

    
6280
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6281
   /* Alpha specific */
6282
    case TARGET_NR_getxuid:
6283
         {
6284
            uid_t euid;
6285
            euid=geteuid();
6286
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6287
         }
6288
        ret = get_errno(getuid());
6289
        break;
6290
#endif
6291
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6292
   /* Alpha specific */
6293
    case TARGET_NR_getxgid:
6294
         {
6295
            uid_t egid;
6296
            egid=getegid();
6297
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6298
         }
6299
        ret = get_errno(getgid());
6300
        break;
6301
#endif
6302

    
6303
#ifdef TARGET_NR_getgid32
6304
    case TARGET_NR_getgid32:
6305
        ret = get_errno(getgid());
6306
        break;
6307
#endif
6308
#ifdef TARGET_NR_geteuid32
6309
    case TARGET_NR_geteuid32:
6310
        ret = get_errno(geteuid());
6311
        break;
6312
#endif
6313
#ifdef TARGET_NR_getegid32
6314
    case TARGET_NR_getegid32:
6315
        ret = get_errno(getegid());
6316
        break;
6317
#endif
6318
#ifdef TARGET_NR_setreuid32
6319
    case TARGET_NR_setreuid32:
6320
        ret = get_errno(setreuid(arg1, arg2));
6321
        break;
6322
#endif
6323
#ifdef TARGET_NR_setregid32
6324
    case TARGET_NR_setregid32:
6325
        ret = get_errno(setregid(arg1, arg2));
6326
        break;
6327
#endif
6328
#ifdef TARGET_NR_getgroups32
6329
    case TARGET_NR_getgroups32:
6330
        {
6331
            int gidsetsize = arg1;
6332
            uint32_t *target_grouplist;
6333
            gid_t *grouplist;
6334
            int i;
6335

    
6336
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6337
            ret = get_errno(getgroups(gidsetsize, grouplist));
6338
            if (gidsetsize == 0)
6339
                break;
6340
            if (!is_error(ret)) {
6341
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6342
                if (!target_grouplist) {
6343
                    ret = -TARGET_EFAULT;
6344
                    goto fail;
6345
                }
6346
                for(i = 0;i < ret; i++)
6347
                    target_grouplist[i] = tswap32(grouplist[i]);
6348
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6349
            }
6350
        }
6351
        break;
6352
#endif
6353
#ifdef TARGET_NR_setgroups32
6354
    case TARGET_NR_setgroups32:
6355
        {
6356
            int gidsetsize = arg1;
6357
            uint32_t *target_grouplist;
6358
            gid_t *grouplist;
6359
            int i;
6360

    
6361
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6362
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6363
            if (!target_grouplist) {
6364
                ret = -TARGET_EFAULT;
6365
                goto fail;
6366
            }
6367
            for(i = 0;i < gidsetsize; i++)
6368
                grouplist[i] = tswap32(target_grouplist[i]);
6369
            unlock_user(target_grouplist, arg2, 0);
6370
            ret = get_errno(setgroups(gidsetsize, grouplist));
6371
        }
6372
        break;
6373
#endif
6374
#ifdef TARGET_NR_fchown32
6375
    case TARGET_NR_fchown32:
6376
        ret = get_errno(fchown(arg1, arg2, arg3));
6377
        break;
6378
#endif
6379
#ifdef TARGET_NR_setresuid32
6380
    case TARGET_NR_setresuid32:
6381
        ret = get_errno(setresuid(arg1, arg2, arg3));
6382
        break;
6383
#endif
6384
#ifdef TARGET_NR_getresuid32
6385
    case TARGET_NR_getresuid32:
6386
        {
6387
            uid_t ruid, euid, suid;
6388
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6389
            if (!is_error(ret)) {
6390
                if (put_user_u32(ruid, arg1)
6391
                    || put_user_u32(euid, arg2)
6392
                    || put_user_u32(suid, arg3))
6393
                    goto efault;
6394
            }
6395
        }
6396
        break;
6397
#endif
6398
#ifdef TARGET_NR_setresgid32
6399
    case TARGET_NR_setresgid32:
6400
        ret = get_errno(setresgid(arg1, arg2, arg3));
6401
        break;
6402
#endif
6403
#ifdef TARGET_NR_getresgid32
6404
    case TARGET_NR_getresgid32:
6405
        {
6406
            gid_t rgid, egid, sgid;
6407
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6408
            if (!is_error(ret)) {
6409
                if (put_user_u32(rgid, arg1)
6410
                    || put_user_u32(egid, arg2)
6411
                    || put_user_u32(sgid, arg3))
6412
                    goto efault;
6413
            }
6414
        }
6415
        break;
6416
#endif
6417
#ifdef TARGET_NR_chown32
6418
    case TARGET_NR_chown32:
6419
        if (!(p = lock_user_string(arg1)))
6420
            goto efault;
6421
        ret = get_errno(chown(p, arg2, arg3));
6422
        unlock_user(p, arg1, 0);
6423
        break;
6424
#endif
6425
#ifdef TARGET_NR_setuid32
6426
    case TARGET_NR_setuid32:
6427
        ret = get_errno(setuid(arg1));
6428
        break;
6429
#endif
6430
#ifdef TARGET_NR_setgid32
6431
    case TARGET_NR_setgid32:
6432
        ret = get_errno(setgid(arg1));
6433
        break;
6434
#endif
6435
#ifdef TARGET_NR_setfsuid32
6436
    case TARGET_NR_setfsuid32:
6437
        ret = get_errno(setfsuid(arg1));
6438
        break;
6439
#endif
6440
#ifdef TARGET_NR_setfsgid32
6441
    case TARGET_NR_setfsgid32:
6442
        ret = get_errno(setfsgid(arg1));
6443
        break;
6444
#endif
6445

    
6446
    case TARGET_NR_pivot_root:
6447
        goto unimplemented;
6448
#ifdef TARGET_NR_mincore
6449
    case TARGET_NR_mincore:
6450
        {
6451
            void *a;
6452
            ret = -TARGET_EFAULT;
6453
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6454
                goto efault;
6455
            if (!(p = lock_user_string(arg3)))
6456
                goto mincore_fail;
6457
            ret = get_errno(mincore(a, arg2, p));
6458
            unlock_user(p, arg3, ret);
6459
            mincore_fail:
6460
            unlock_user(a, arg1, 0);
6461
        }
6462
        break;
6463
#endif
6464
#ifdef TARGET_NR_arm_fadvise64_64
6465
    case TARGET_NR_arm_fadvise64_64:
6466
        {
6467
                /*
6468
                 * arm_fadvise64_64 looks like fadvise64_64 but
6469
                 * with different argument order
6470
                 */
6471
                abi_long temp;
6472
                temp = arg3;
6473
                arg3 = arg4;
6474
                arg4 = temp;
6475
        }
6476
#endif
6477
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6478
#ifdef TARGET_NR_fadvise64_64
6479
    case TARGET_NR_fadvise64_64:
6480
#endif
6481
        /* This is a hint, so ignoring and returning success is ok.  */
6482
        ret = get_errno(0);
6483
        break;
6484
#endif
6485
#ifdef TARGET_NR_madvise
6486
    case TARGET_NR_madvise:
6487
        /* A straight passthrough may not be safe because qemu sometimes
6488
           turns private flie-backed mappings into anonymous mappings.
6489
           This will break MADV_DONTNEED.
6490
           This is a hint, so ignoring and returning success is ok.  */
6491
        ret = get_errno(0);
6492
        break;
6493
#endif
6494
#if TARGET_ABI_BITS == 32
6495
    case TARGET_NR_fcntl64:
6496
    {
6497
        int cmd;
6498
        struct flock64 fl;
6499
        struct target_flock64 *target_fl;
6500
#ifdef TARGET_ARM
6501
        struct target_eabi_flock64 *target_efl;
6502
#endif
6503

    
6504
        switch(arg2){
6505
        case TARGET_F_GETLK64:
6506
            cmd = F_GETLK64;
6507
            break;
6508
        case TARGET_F_SETLK64:
6509
            cmd = F_SETLK64;
6510
            break;
6511
        case TARGET_F_SETLKW64:
6512
            cmd = F_SETLK64;
6513
            break;
6514
        default:
6515
            cmd = arg2;
6516
            break;
6517
        }
6518

    
6519
        switch(arg2) {
6520
        case TARGET_F_GETLK64:
6521
#ifdef TARGET_ARM
6522
            if (((CPUARMState *)cpu_env)->eabi) {
6523
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6524
                    goto efault;
6525
                fl.l_type = tswap16(target_efl->l_type);
6526
                fl.l_whence = tswap16(target_efl->l_whence);
6527
                fl.l_start = tswap64(target_efl->l_start);
6528
                fl.l_len = tswap64(target_efl->l_len);
6529
                fl.l_pid = tswapl(target_efl->l_pid);
6530
                unlock_user_struct(target_efl, arg3, 0);
6531
            } else
6532
#endif
6533
            {
6534
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6535
                    goto efault;
6536
                fl.l_type = tswap16(target_fl->l_type);
6537
                fl.l_whence = tswap16(target_fl->l_whence);
6538
                fl.l_start = tswap64(target_fl->l_start);
6539
                fl.l_len = tswap64(target_fl->l_len);
6540
                fl.l_pid = tswapl(target_fl->l_pid);
6541
                unlock_user_struct(target_fl, arg3, 0);
6542
            }
6543
            ret = get_errno(fcntl(arg1, cmd, &fl));
6544
            if (ret == 0) {
6545
#ifdef TARGET_ARM
6546
                if (((CPUARMState *)cpu_env)->eabi) {
6547
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6548
                        goto efault;
6549
                    target_efl->l_type = tswap16(fl.l_type);
6550
                    target_efl->l_whence = tswap16(fl.l_whence);
6551
                    target_efl->l_start = tswap64(fl.l_start);
6552
                    target_efl->l_len = tswap64(fl.l_len);
6553
                    target_efl->l_pid = tswapl(fl.l_pid);
6554
                    unlock_user_struct(target_efl, arg3, 1);
6555
                } else
6556
#endif
6557
                {
6558
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6559
                        goto efault;
6560
                    target_fl->l_type = tswap16(fl.l_type);
6561
                    target_fl->l_whence = tswap16(fl.l_whence);
6562
                    target_fl->l_start = tswap64(fl.l_start);
6563
                    target_fl->l_len = tswap64(fl.l_len);
6564
                    target_fl->l_pid = tswapl(fl.l_pid);
6565
                    unlock_user_struct(target_fl, arg3, 1);
6566
                }
6567
            }
6568
            break;
6569

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

    
6688
#ifdef TARGET_NR_clock_gettime
6689
    case TARGET_NR_clock_gettime:
6690
    {
6691
        struct timespec ts;
6692
        ret = get_errno(clock_gettime(arg1, &ts));
6693
        if (!is_error(ret)) {
6694
            host_to_target_timespec(arg2, &ts);
6695
        }
6696
        break;
6697
    }
6698
#endif
6699
#ifdef TARGET_NR_clock_getres
6700
    case TARGET_NR_clock_getres:
6701
    {
6702
        struct timespec ts;
6703
        ret = get_errno(clock_getres(arg1, &ts));
6704
        if (!is_error(ret)) {
6705
            host_to_target_timespec(arg2, &ts);
6706
        }
6707
        break;
6708
    }
6709
#endif
6710
#ifdef TARGET_NR_clock_nanosleep
6711
    case TARGET_NR_clock_nanosleep:
6712
    {
6713
        struct timespec ts;
6714
        target_to_host_timespec(&ts, arg3);
6715
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6716
        if (arg4)
6717
            host_to_target_timespec(arg4, &ts);
6718
        break;
6719
    }
6720
#endif
6721

    
6722
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6723
    case TARGET_NR_set_tid_address:
6724
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6725
        break;
6726
#endif
6727

    
6728
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6729
    case TARGET_NR_tkill:
6730
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6731
        break;
6732
#endif
6733

    
6734
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6735
    case TARGET_NR_tgkill:
6736
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6737
                        target_to_host_signal(arg3)));
6738
        break;
6739
#endif
6740

    
6741
#ifdef TARGET_NR_set_robust_list
6742
    case TARGET_NR_set_robust_list:
6743
        goto unimplemented_nowarn;
6744
#endif
6745

    
6746
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6747
    case TARGET_NR_utimensat:
6748
        {
6749
            struct timespec *tsp, ts[2];
6750
            if (!arg3) {
6751
                tsp = NULL;
6752
            } else {
6753
                target_to_host_timespec(ts, arg3);
6754
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6755
                tsp = ts;
6756
            }
6757
            if (!arg2)
6758
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6759
            else {
6760
                if (!(p = lock_user_string(arg2))) {
6761
                    ret = -TARGET_EFAULT;
6762
                    goto fail;
6763
                }
6764
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6765
                unlock_user(p, arg2, 0);
6766
            }
6767
        }
6768
        break;
6769
#endif
6770
#if defined(USE_NPTL)
6771
    case TARGET_NR_futex:
6772
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6773
        break;
6774
#endif
6775
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6776
    case TARGET_NR_inotify_init:
6777
        ret = get_errno(sys_inotify_init());
6778
        break;
6779
#endif
6780
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6781
    case TARGET_NR_inotify_add_watch:
6782
        p = lock_user_string(arg2);
6783
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6784
        unlock_user(p, arg2, 0);
6785
        break;
6786
#endif
6787
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6788
    case TARGET_NR_inotify_rm_watch:
6789
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6790
        break;
6791
#endif
6792

    
6793
#ifdef TARGET_NR_mq_open
6794
    case TARGET_NR_mq_open:
6795
        {
6796
            struct mq_attr posix_mq_attr;
6797

    
6798
            p = lock_user_string(arg1 - 1);
6799
            if (arg4 != 0)
6800
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6801
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6802
            unlock_user (p, arg1, 0);
6803
        }
6804
        break;
6805

    
6806
    case TARGET_NR_mq_unlink:
6807
        p = lock_user_string(arg1 - 1);
6808
        ret = get_errno(mq_unlink(p));
6809
        unlock_user (p, arg1, 0);
6810
        break;
6811

    
6812
    case TARGET_NR_mq_timedsend:
6813
        {
6814
            struct timespec ts;
6815

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

    
6828
    case TARGET_NR_mq_timedreceive:
6829
        {
6830
            struct timespec ts;
6831
            unsigned int prio;
6832

    
6833
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6834
            if (arg5 != 0) {
6835
                target_to_host_timespec(&ts, arg5);
6836
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6837
                host_to_target_timespec(arg5, &ts);
6838
            }
6839
            else
6840
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6841
            unlock_user (p, arg2, arg3);
6842
            if (arg4 != 0)
6843
                put_user_u32(prio, arg4);
6844
        }
6845
        break;
6846

    
6847
    /* Not implemented for now... */
6848
/*     case TARGET_NR_mq_notify: */
6849
/*         break; */
6850

    
6851
    case TARGET_NR_mq_getsetattr:
6852
        {
6853
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6854
            ret = 0;
6855
            if (arg3 != 0) {
6856
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6857
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6858
            }
6859
            if (arg2 != 0) {
6860
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6861
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6862
            }
6863

    
6864
        }
6865
        break;
6866
#endif
6867

    
6868
#ifdef CONFIG_SPLICE
6869
#ifdef TARGET_NR_tee
6870
    case TARGET_NR_tee:
6871
        {
6872
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
6873
        }
6874
        break;
6875
#endif
6876
#ifdef TARGET_NR_splice
6877
    case TARGET_NR_splice:
6878
        {
6879
            loff_t loff_in, loff_out;
6880
            loff_t *ploff_in = NULL, *ploff_out = NULL;
6881
            if(arg2) {
6882
                get_user_u64(loff_in, arg2);
6883
                ploff_in = &loff_in;
6884
            }
6885
            if(arg4) {
6886
                get_user_u64(loff_out, arg2);
6887
                ploff_out = &loff_out;
6888
            }
6889
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
6890
        }
6891
        break;
6892
#endif
6893
#ifdef TARGET_NR_vmsplice
6894
        case TARGET_NR_vmsplice:
6895
        {
6896
            int count = arg3;
6897
            struct iovec *vec;
6898

    
6899
            vec = alloca(count * sizeof(struct iovec));
6900
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6901
                goto efault;
6902
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
6903
            unlock_iovec(vec, arg2, count, 0);
6904
        }
6905
        break;
6906
#endif
6907
#endif /* CONFIG_SPLICE */
6908
    default:
6909
    unimplemented:
6910
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6911
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6912
    unimplemented_nowarn:
6913
#endif
6914
        ret = -TARGET_ENOSYS;
6915
        break;
6916
    }
6917
fail:
6918
#ifdef DEBUG
6919
    gemu_log(" = %ld\n", ret);
6920
#endif
6921
    if(do_strace)
6922
        print_syscall_ret(num, ret);
6923
    return ret;
6924
efault:
6925
    ret = -TARGET_EFAULT;
6926
    goto fail;
6927
}