Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ c227f099

History | View | Annotate | Download (214.9 kB)

1
/*
2
 *  Linux syscalls
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#define _ATFILE_SOURCE
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#include <elf.h>
25
#include <endian.h>
26
#include <errno.h>
27
#include <unistd.h>
28
#include <fcntl.h>
29
#include <time.h>
30
#include <limits.h>
31
#include <sys/types.h>
32
#include <sys/ipc.h>
33
#include <sys/msg.h>
34
#include <sys/wait.h>
35
#include <sys/time.h>
36
#include <sys/stat.h>
37
#include <sys/mount.h>
38
#include <sys/prctl.h>
39
#include <sys/resource.h>
40
#include <sys/mman.h>
41
#include <sys/swap.h>
42
#include <signal.h>
43
#include <sched.h>
44
#include <sys/socket.h>
45
#include <sys/un.h>
46
#include <sys/uio.h>
47
#include <sys/poll.h>
48
#include <sys/times.h>
49
#include <sys/shm.h>
50
#include <sys/sem.h>
51
#include <sys/statfs.h>
52
#include <utime.h>
53
#include <sys/sysinfo.h>
54
#include <sys/utsname.h>
55
//#include <sys/user.h>
56
#include <netinet/ip.h>
57
#include <netinet/tcp.h>
58
#include <qemu-common.h>
59
#ifdef TARGET_GPROF
60
#include <sys/gmon.h>
61
#endif
62
#ifdef CONFIG_EVENTFD
63
#include <sys/eventfd.h>
64
#endif
65

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

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

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

    
87
#if defined(CONFIG_USE_NPTL)
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
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
200
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
201
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
202
#endif
203
_syscall2(int, sys_getpriority, int, which, int, who);
204
#if defined(TARGET_NR__llseek) && !defined (__x86_64__)
205
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
206
          loff_t *, res, uint, wh);
207
#endif
208
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
209
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
210
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
211
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
212
#endif
213
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
214
_syscall2(int,sys_tkill,int,tid,int,sig)
215
#endif
216
#ifdef __NR_exit_group
217
_syscall1(int,exit_group,int,error_code)
218
#endif
219
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
220
_syscall1(int,set_tid_address,int *,tidptr)
221
#endif
222
#if defined(CONFIG_USE_NPTL)
223
#if defined(TARGET_NR_futex) && defined(__NR_futex)
224
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
225
          const struct timespec *,timeout,int *,uaddr2,int,val3)
226
#endif
227
#endif
228

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

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

    
256
static int sys_uname(struct new_utsname *buf)
257
{
258
  struct utsname uts_buf;
259

    
260
  if (uname(&uts_buf) < 0)
261
      return (-1);
262

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

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

    
280
#undef COPY_UTSNAME_FIELD
281
}
282

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

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

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

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

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

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

    
467
#endif /* CONFIG_ATFILE */
468

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

    
485
#ifdef CONFIG_INOTIFY
486
#include <sys/inotify.h>
487

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

    
513

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

    
520
#define ERRNO_TABLE_SIZE 1200
521

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

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

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

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

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

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

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

    
671
static abi_ulong target_brk;
672
static abi_ulong target_original_brk;
673

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

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

    
686
    if (!new_brk)
687
        return target_brk;
688
    if (new_brk < target_original_brk)
689
        return target_brk;
690

    
691
    brk_page = HOST_PAGE_ALIGN(target_brk);
692

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

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

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

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

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

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

    
738
    unlock_user(target_fds, target_fds_addr, 0);
739

    
740
    return 0;
741
}
742

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

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

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

    
768
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
769

    
770
    return 0;
771
}
772

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

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

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

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

    
815
    return 0;
816
}
817

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

    
823
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
824
        return -TARGET_EFAULT;
825

    
826
    __get_user(tv->tv_sec, &target_tv->tv_sec);
827
    __get_user(tv->tv_usec, &target_tv->tv_usec);
828

    
829
    unlock_user_struct(target_tv, target_tv_addr, 0);
830

    
831
    return 0;
832
}
833

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

    
839
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
840
        return -TARGET_EFAULT;
841

    
842
    __put_user(tv->tv_sec, &target_tv->tv_sec);
843
    __put_user(tv->tv_usec, &target_tv->tv_usec);
844

    
845
    unlock_user_struct(target_tv, target_tv_addr, 1);
846

    
847
    return 0;
848
}
849

    
850
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
851
#include <mqueue.h>
852

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

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

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

    
867
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
868

    
869
    return 0;
870
}
871

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

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

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

    
886
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
887

    
888
    return 0;
889
}
890
#endif
891

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

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

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

    
932
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
933

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

    
942
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
943
            return -TARGET_EFAULT;
944
    }
945

    
946
    return ret;
947
}
948

    
949
static abi_long do_pipe2(int host_pipe[], int flags)
950
{
951
#ifdef CONFIG_PIPE2
952
    return pipe2(host_pipe, flags);
953
#else
954
    return -ENOSYS;
955
#endif
956
}
957

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

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

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

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

    
995
    return 0;
996
}
997

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

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

    
1010
    sa_family = tswap16(target_saddr->sa_family);
1011

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

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

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

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

    
1035
    return 0;
1036
}
1037

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

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

    
1051
    return 0;
1052
}
1053

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

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

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

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

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

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

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

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

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

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

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

    
1133
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1134

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1465
    return 0;
1466
}
1467

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

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

    
1505
    if (addrlen < 0)
1506
        return -TARGET_EINVAL;
1507

    
1508
    addr = alloca(addrlen+1);
1509

    
1510
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1511
    if (ret)
1512
        return ret;
1513

    
1514
    return get_errno(bind(sockfd, addr, addrlen));
1515
}
1516

    
1517
/* do_connect() Must return target values and target errnos. */
1518
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1519
                           socklen_t addrlen)
1520
{
1521
    void *addr;
1522
    abi_long ret;
1523

    
1524
    if (addrlen < 0)
1525
        return -TARGET_EINVAL;
1526

    
1527
    addr = alloca(addrlen);
1528

    
1529
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1530
    if (ret)
1531
        return ret;
1532

    
1533
    return get_errno(connect(sockfd, addr, addrlen));
1534
}
1535

    
1536
/* do_sendrecvmsg() Must return target values and target errnos. */
1537
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1538
                               int flags, int send)
1539
{
1540
    abi_long ret, len;
1541
    struct target_msghdr *msgp;
1542
    struct msghdr msg;
1543
    int count;
1544
    struct iovec *vec;
1545
    abi_ulong target_vec;
1546

    
1547
    /* FIXME */
1548
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1549
                          msgp,
1550
                          target_msg,
1551
                          send ? 1 : 0))
1552
        return -TARGET_EFAULT;
1553
    if (msgp->msg_name) {
1554
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1555
        msg.msg_name = alloca(msg.msg_namelen);
1556
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1557
                                msg.msg_namelen);
1558
        if (ret) {
1559
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1560
            return ret;
1561
        }
1562
    } else {
1563
        msg.msg_name = NULL;
1564
        msg.msg_namelen = 0;
1565
    }
1566
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1567
    msg.msg_control = alloca(msg.msg_controllen);
1568
    msg.msg_flags = tswap32(msgp->msg_flags);
1569

    
1570
    count = tswapl(msgp->msg_iovlen);
1571
    vec = alloca(count * sizeof(struct iovec));
1572
    target_vec = tswapl(msgp->msg_iov);
1573
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1574
    msg.msg_iovlen = count;
1575
    msg.msg_iov = vec;
1576

    
1577
    if (send) {
1578
        ret = target_to_host_cmsg(&msg, msgp);
1579
        if (ret == 0)
1580
            ret = get_errno(sendmsg(fd, &msg, flags));
1581
    } else {
1582
        ret = get_errno(recvmsg(fd, &msg, flags));
1583
        if (!is_error(ret)) {
1584
            len = ret;
1585
            ret = host_to_target_cmsg(msgp, &msg);
1586
            if (!is_error(ret))
1587
                ret = len;
1588
        }
1589
    }
1590
    unlock_iovec(vec, target_vec, count, !send);
1591
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1592
    return ret;
1593
}
1594

    
1595
/* do_accept() Must return target values and target errnos. */
1596
static abi_long do_accept(int fd, abi_ulong target_addr,
1597
                          abi_ulong target_addrlen_addr)
1598
{
1599
    socklen_t addrlen;
1600
    void *addr;
1601
    abi_long ret;
1602

    
1603
    if (target_addr == 0)
1604
       return get_errno(accept(fd, NULL, NULL));
1605

    
1606
    /* linux returns EINVAL if addrlen pointer is invalid */
1607
    if (get_user_u32(addrlen, target_addrlen_addr))
1608
        return -TARGET_EINVAL;
1609

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

    
1613
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1614
        return -TARGET_EINVAL;
1615

    
1616
    addr = alloca(addrlen);
1617

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

    
1627
/* do_getpeername() Must return target values and target errnos. */
1628
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1629
                               abi_ulong target_addrlen_addr)
1630
{
1631
    socklen_t addrlen;
1632
    void *addr;
1633
    abi_long ret;
1634

    
1635
    if (get_user_u32(addrlen, target_addrlen_addr))
1636
        return -TARGET_EFAULT;
1637

    
1638
    if (addrlen < 0)
1639
        return -TARGET_EINVAL;
1640

    
1641
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1642
        return -TARGET_EFAULT;
1643

    
1644
    addr = alloca(addrlen);
1645

    
1646
    ret = get_errno(getpeername(fd, addr, &addrlen));
1647
    if (!is_error(ret)) {
1648
        host_to_target_sockaddr(target_addr, addr, addrlen);
1649
        if (put_user_u32(addrlen, target_addrlen_addr))
1650
            ret = -TARGET_EFAULT;
1651
    }
1652
    return ret;
1653
}
1654

    
1655
/* do_getsockname() Must return target values and target errnos. */
1656
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1657
                               abi_ulong target_addrlen_addr)
1658
{
1659
    socklen_t addrlen;
1660
    void *addr;
1661
    abi_long ret;
1662

    
1663
    if (get_user_u32(addrlen, target_addrlen_addr))
1664
        return -TARGET_EFAULT;
1665

    
1666
    if (addrlen < 0)
1667
        return -TARGET_EINVAL;
1668

    
1669
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1670
        return -TARGET_EFAULT;
1671

    
1672
    addr = alloca(addrlen);
1673

    
1674
    ret = get_errno(getsockname(fd, addr, &addrlen));
1675
    if (!is_error(ret)) {
1676
        host_to_target_sockaddr(target_addr, addr, addrlen);
1677
        if (put_user_u32(addrlen, target_addrlen_addr))
1678
            ret = -TARGET_EFAULT;
1679
    }
1680
    return ret;
1681
}
1682

    
1683
/* do_socketpair() Must return target values and target errnos. */
1684
static abi_long do_socketpair(int domain, int type, int protocol,
1685
                              abi_ulong target_tab_addr)
1686
{
1687
    int tab[2];
1688
    abi_long ret;
1689

    
1690
    ret = get_errno(socketpair(domain, type, protocol, tab));
1691
    if (!is_error(ret)) {
1692
        if (put_user_s32(tab[0], target_tab_addr)
1693
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1694
            ret = -TARGET_EFAULT;
1695
    }
1696
    return ret;
1697
}
1698

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

    
1707
    if (addrlen < 0)
1708
        return -TARGET_EINVAL;
1709

    
1710
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1711
    if (!host_msg)
1712
        return -TARGET_EFAULT;
1713
    if (target_addr) {
1714
        addr = alloca(addrlen);
1715
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1716
        if (ret) {
1717
            unlock_user(host_msg, msg, 0);
1718
            return ret;
1719
        }
1720
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1721
    } else {
1722
        ret = get_errno(send(fd, host_msg, len, flags));
1723
    }
1724
    unlock_user(host_msg, msg, 0);
1725
    return ret;
1726
}
1727

    
1728
/* do_recvfrom() Must return target values and target errnos. */
1729
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1730
                            abi_ulong target_addr,
1731
                            abi_ulong target_addrlen)
1732
{
1733
    socklen_t addrlen;
1734
    void *addr;
1735
    void *host_msg;
1736
    abi_long ret;
1737

    
1738
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1739
    if (!host_msg)
1740
        return -TARGET_EFAULT;
1741
    if (target_addr) {
1742
        if (get_user_u32(addrlen, target_addrlen)) {
1743
            ret = -TARGET_EFAULT;
1744
            goto fail;
1745
        }
1746
        if (addrlen < 0) {
1747
            ret = -TARGET_EINVAL;
1748
            goto fail;
1749
        }
1750
        addr = alloca(addrlen);
1751
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1752
    } else {
1753
        addr = NULL; /* To keep compiler quiet.  */
1754
        ret = get_errno(recv(fd, host_msg, len, flags));
1755
    }
1756
    if (!is_error(ret)) {
1757
        if (target_addr) {
1758
            host_to_target_sockaddr(target_addr, addr, addrlen);
1759
            if (put_user_u32(addrlen, target_addrlen)) {
1760
                ret = -TARGET_EFAULT;
1761
                goto fail;
1762
            }
1763
        }
1764
        unlock_user(host_msg, msg, len);
1765
    } else {
1766
fail:
1767
        unlock_user(host_msg, msg, 0);
1768
    }
1769
    return ret;
1770
}
1771

    
1772
#ifdef TARGET_NR_socketcall
1773
/* do_socketcall() Must return target values and target errnos. */
1774
static abi_long do_socketcall(int num, abi_ulong vptr)
1775
{
1776
    abi_long ret;
1777
    const int n = sizeof(abi_ulong);
1778

    
1779
    switch(num) {
1780
    case SOCKOP_socket:
1781
        {
1782
            abi_ulong domain, type, protocol;
1783

    
1784
            if (get_user_ual(domain, vptr)
1785
                || get_user_ual(type, vptr + n)
1786
                || get_user_ual(protocol, vptr + 2 * n))
1787
                return -TARGET_EFAULT;
1788

    
1789
            ret = do_socket(domain, type, protocol);
1790
        }
1791
        break;
1792
    case SOCKOP_bind:
1793
        {
1794
            abi_ulong sockfd;
1795
            abi_ulong target_addr;
1796
            socklen_t addrlen;
1797

    
1798
            if (get_user_ual(sockfd, vptr)
1799
                || get_user_ual(target_addr, vptr + n)
1800
                || get_user_ual(addrlen, vptr + 2 * n))
1801
                return -TARGET_EFAULT;
1802

    
1803
            ret = do_bind(sockfd, target_addr, addrlen);
1804
        }
1805
        break;
1806
    case SOCKOP_connect:
1807
        {
1808
            abi_ulong sockfd;
1809
            abi_ulong target_addr;
1810
            socklen_t addrlen;
1811

    
1812
            if (get_user_ual(sockfd, vptr)
1813
                || get_user_ual(target_addr, vptr + n)
1814
                || get_user_ual(addrlen, vptr + 2 * n))
1815
                return -TARGET_EFAULT;
1816

    
1817
            ret = do_connect(sockfd, target_addr, addrlen);
1818
        }
1819
        break;
1820
    case SOCKOP_listen:
1821
        {
1822
            abi_ulong sockfd, backlog;
1823

    
1824
            if (get_user_ual(sockfd, vptr)
1825
                || get_user_ual(backlog, vptr + n))
1826
                return -TARGET_EFAULT;
1827

    
1828
            ret = get_errno(listen(sockfd, backlog));
1829
        }
1830
        break;
1831
    case SOCKOP_accept:
1832
        {
1833
            abi_ulong sockfd;
1834
            abi_ulong target_addr, target_addrlen;
1835

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

    
1841
            ret = do_accept(sockfd, target_addr, target_addrlen);
1842
        }
1843
        break;
1844
    case SOCKOP_getsockname:
1845
        {
1846
            abi_ulong sockfd;
1847
            abi_ulong target_addr, target_addrlen;
1848

    
1849
            if (get_user_ual(sockfd, vptr)
1850
                || get_user_ual(target_addr, vptr + n)
1851
                || get_user_ual(target_addrlen, vptr + 2 * n))
1852
                return -TARGET_EFAULT;
1853

    
1854
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1855
        }
1856
        break;
1857
    case SOCKOP_getpeername:
1858
        {
1859
            abi_ulong sockfd;
1860
            abi_ulong target_addr, target_addrlen;
1861

    
1862
            if (get_user_ual(sockfd, vptr)
1863
                || get_user_ual(target_addr, vptr + n)
1864
                || get_user_ual(target_addrlen, vptr + 2 * n))
1865
                return -TARGET_EFAULT;
1866

    
1867
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1868
        }
1869
        break;
1870
    case SOCKOP_socketpair:
1871
        {
1872
            abi_ulong domain, type, protocol;
1873
            abi_ulong tab;
1874

    
1875
            if (get_user_ual(domain, vptr)
1876
                || get_user_ual(type, vptr + n)
1877
                || get_user_ual(protocol, vptr + 2 * n)
1878
                || get_user_ual(tab, vptr + 3 * n))
1879
                return -TARGET_EFAULT;
1880

    
1881
            ret = do_socketpair(domain, type, protocol, tab);
1882
        }
1883
        break;
1884
    case SOCKOP_send:
1885
        {
1886
            abi_ulong sockfd;
1887
            abi_ulong msg;
1888
            size_t len;
1889
            abi_ulong flags;
1890

    
1891
            if (get_user_ual(sockfd, vptr)
1892
                || get_user_ual(msg, vptr + n)
1893
                || get_user_ual(len, vptr + 2 * n)
1894
                || get_user_ual(flags, vptr + 3 * n))
1895
                return -TARGET_EFAULT;
1896

    
1897
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1898
        }
1899
        break;
1900
    case SOCKOP_recv:
1901
        {
1902
            abi_ulong sockfd;
1903
            abi_ulong msg;
1904
            size_t len;
1905
            abi_ulong flags;
1906

    
1907
            if (get_user_ual(sockfd, vptr)
1908
                || get_user_ual(msg, vptr + n)
1909
                || get_user_ual(len, vptr + 2 * n)
1910
                || get_user_ual(flags, vptr + 3 * n))
1911
                return -TARGET_EFAULT;
1912

    
1913
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1914
        }
1915
        break;
1916
    case SOCKOP_sendto:
1917
        {
1918
            abi_ulong sockfd;
1919
            abi_ulong msg;
1920
            size_t len;
1921
            abi_ulong flags;
1922
            abi_ulong addr;
1923
            socklen_t addrlen;
1924

    
1925
            if (get_user_ual(sockfd, vptr)
1926
                || get_user_ual(msg, vptr + n)
1927
                || get_user_ual(len, vptr + 2 * n)
1928
                || get_user_ual(flags, vptr + 3 * n)
1929
                || get_user_ual(addr, vptr + 4 * n)
1930
                || get_user_ual(addrlen, vptr + 5 * n))
1931
                return -TARGET_EFAULT;
1932

    
1933
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1934
        }
1935
        break;
1936
    case SOCKOP_recvfrom:
1937
        {
1938
            abi_ulong sockfd;
1939
            abi_ulong msg;
1940
            size_t len;
1941
            abi_ulong flags;
1942
            abi_ulong addr;
1943
            socklen_t addrlen;
1944

    
1945
            if (get_user_ual(sockfd, vptr)
1946
                || get_user_ual(msg, vptr + n)
1947
                || get_user_ual(len, vptr + 2 * n)
1948
                || get_user_ual(flags, vptr + 3 * n)
1949
                || get_user_ual(addr, vptr + 4 * n)
1950
                || get_user_ual(addrlen, vptr + 5 * n))
1951
                return -TARGET_EFAULT;
1952

    
1953
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1954
        }
1955
        break;
1956
    case SOCKOP_shutdown:
1957
        {
1958
            abi_ulong sockfd, how;
1959

    
1960
            if (get_user_ual(sockfd, vptr)
1961
                || get_user_ual(how, vptr + n))
1962
                return -TARGET_EFAULT;
1963

    
1964
            ret = get_errno(shutdown(sockfd, how));
1965
        }
1966
        break;
1967
    case SOCKOP_sendmsg:
1968
    case SOCKOP_recvmsg:
1969
        {
1970
            abi_ulong fd;
1971
            abi_ulong target_msg;
1972
            abi_ulong flags;
1973

    
1974
            if (get_user_ual(fd, vptr)
1975
                || get_user_ual(target_msg, vptr + n)
1976
                || get_user_ual(flags, vptr + 2 * n))
1977
                return -TARGET_EFAULT;
1978

    
1979
            ret = do_sendrecvmsg(fd, target_msg, flags,
1980
                                 (num == SOCKOP_sendmsg));
1981
        }
1982
        break;
1983
    case SOCKOP_setsockopt:
1984
        {
1985
            abi_ulong sockfd;
1986
            abi_ulong level;
1987
            abi_ulong optname;
1988
            abi_ulong optval;
1989
            socklen_t optlen;
1990

    
1991
            if (get_user_ual(sockfd, vptr)
1992
                || get_user_ual(level, vptr + n)
1993
                || get_user_ual(optname, vptr + 2 * n)
1994
                || get_user_ual(optval, vptr + 3 * n)
1995
                || get_user_ual(optlen, vptr + 4 * n))
1996
                return -TARGET_EFAULT;
1997

    
1998
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1999
        }
2000
        break;
2001
    case SOCKOP_getsockopt:
2002
        {
2003
            abi_ulong sockfd;
2004
            abi_ulong level;
2005
            abi_ulong optname;
2006
            abi_ulong optval;
2007
            socklen_t optlen;
2008

    
2009
            if (get_user_ual(sockfd, vptr)
2010
                || get_user_ual(level, vptr + n)
2011
                || get_user_ual(optname, vptr + 2 * n)
2012
                || get_user_ual(optval, vptr + 3 * n)
2013
                || get_user_ual(optlen, vptr + 4 * n))
2014
                return -TARGET_EFAULT;
2015

    
2016
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2017
        }
2018
        break;
2019
    default:
2020
        gemu_log("Unsupported socketcall: %d\n", num);
2021
        ret = -TARGET_ENOSYS;
2022
        break;
2023
    }
2024
    return ret;
2025
}
2026
#endif
2027

    
2028
#define N_SHM_REGIONS        32
2029

    
2030
static struct shm_region {
2031
    abi_ulong        start;
2032
    abi_ulong        size;
2033
} shm_regions[N_SHM_REGIONS];
2034

    
2035
struct target_ipc_perm
2036
{
2037
    abi_long __key;
2038
    abi_ulong uid;
2039
    abi_ulong gid;
2040
    abi_ulong cuid;
2041
    abi_ulong cgid;
2042
    unsigned short int mode;
2043
    unsigned short int __pad1;
2044
    unsigned short int __seq;
2045
    unsigned short int __pad2;
2046
    abi_ulong __unused1;
2047
    abi_ulong __unused2;
2048
};
2049

    
2050
struct target_semid_ds
2051
{
2052
  struct target_ipc_perm sem_perm;
2053
  abi_ulong sem_otime;
2054
  abi_ulong __unused1;
2055
  abi_ulong sem_ctime;
2056
  abi_ulong __unused2;
2057
  abi_ulong sem_nsems;
2058
  abi_ulong __unused3;
2059
  abi_ulong __unused4;
2060
};
2061

    
2062
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2063
                                               abi_ulong target_addr)
2064
{
2065
    struct target_ipc_perm *target_ip;
2066
    struct target_semid_ds *target_sd;
2067

    
2068
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2069
        return -TARGET_EFAULT;
2070
    target_ip = &(target_sd->sem_perm);
2071
    host_ip->__key = tswapl(target_ip->__key);
2072
    host_ip->uid = tswapl(target_ip->uid);
2073
    host_ip->gid = tswapl(target_ip->gid);
2074
    host_ip->cuid = tswapl(target_ip->cuid);
2075
    host_ip->cgid = tswapl(target_ip->cgid);
2076
    host_ip->mode = tswapl(target_ip->mode);
2077
    unlock_user_struct(target_sd, target_addr, 0);
2078
    return 0;
2079
}
2080

    
2081
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2082
                                               struct ipc_perm *host_ip)
2083
{
2084
    struct target_ipc_perm *target_ip;
2085
    struct target_semid_ds *target_sd;
2086

    
2087
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2088
        return -TARGET_EFAULT;
2089
    target_ip = &(target_sd->sem_perm);
2090
    target_ip->__key = tswapl(host_ip->__key);
2091
    target_ip->uid = tswapl(host_ip->uid);
2092
    target_ip->gid = tswapl(host_ip->gid);
2093
    target_ip->cuid = tswapl(host_ip->cuid);
2094
    target_ip->cgid = tswapl(host_ip->cgid);
2095
    target_ip->mode = tswapl(host_ip->mode);
2096
    unlock_user_struct(target_sd, target_addr, 1);
2097
    return 0;
2098
}
2099

    
2100
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2101
                                               abi_ulong target_addr)
2102
{
2103
    struct target_semid_ds *target_sd;
2104

    
2105
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2106
        return -TARGET_EFAULT;
2107
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2108
        return -TARGET_EFAULT;
2109
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2110
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2111
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2112
    unlock_user_struct(target_sd, target_addr, 0);
2113
    return 0;
2114
}
2115

    
2116
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2117
                                               struct semid_ds *host_sd)
2118
{
2119
    struct target_semid_ds *target_sd;
2120

    
2121
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2122
        return -TARGET_EFAULT;
2123
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2124
        return -TARGET_EFAULT;;
2125
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2126
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2127
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2128
    unlock_user_struct(target_sd, target_addr, 1);
2129
    return 0;
2130
}
2131

    
2132
struct target_seminfo {
2133
    int semmap;
2134
    int semmni;
2135
    int semmns;
2136
    int semmnu;
2137
    int semmsl;
2138
    int semopm;
2139
    int semume;
2140
    int semusz;
2141
    int semvmx;
2142
    int semaem;
2143
};
2144

    
2145
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2146
                                              struct seminfo *host_seminfo)
2147
{
2148
    struct target_seminfo *target_seminfo;
2149
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2150
        return -TARGET_EFAULT;
2151
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2152
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2153
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2154
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2155
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2156
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2157
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2158
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2159
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2160
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2161
    unlock_user_struct(target_seminfo, target_addr, 1);
2162
    return 0;
2163
}
2164

    
2165
union semun {
2166
        int val;
2167
        struct semid_ds *buf;
2168
        unsigned short *array;
2169
        struct seminfo *__buf;
2170
};
2171

    
2172
union target_semun {
2173
        int val;
2174
        abi_ulong buf;
2175
        abi_ulong array;
2176
        abi_ulong __buf;
2177
};
2178

    
2179
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2180
                                               abi_ulong target_addr)
2181
{
2182
    int nsems;
2183
    unsigned short *array;
2184
    union semun semun;
2185
    struct semid_ds semid_ds;
2186
    int i, ret;
2187

    
2188
    semun.buf = &semid_ds;
2189

    
2190
    ret = semctl(semid, 0, IPC_STAT, semun);
2191
    if (ret == -1)
2192
        return get_errno(ret);
2193

    
2194
    nsems = semid_ds.sem_nsems;
2195

    
2196
    *host_array = malloc(nsems*sizeof(unsigned short));
2197
    array = lock_user(VERIFY_READ, target_addr,
2198
                      nsems*sizeof(unsigned short), 1);
2199
    if (!array)
2200
        return -TARGET_EFAULT;
2201

    
2202
    for(i=0; i<nsems; i++) {
2203
        __get_user((*host_array)[i], &array[i]);
2204
    }
2205
    unlock_user(array, target_addr, 0);
2206

    
2207
    return 0;
2208
}
2209

    
2210
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2211
                                               unsigned short **host_array)
2212
{
2213
    int nsems;
2214
    unsigned short *array;
2215
    union semun semun;
2216
    struct semid_ds semid_ds;
2217
    int i, ret;
2218

    
2219
    semun.buf = &semid_ds;
2220

    
2221
    ret = semctl(semid, 0, IPC_STAT, semun);
2222
    if (ret == -1)
2223
        return get_errno(ret);
2224

    
2225
    nsems = semid_ds.sem_nsems;
2226

    
2227
    array = lock_user(VERIFY_WRITE, target_addr,
2228
                      nsems*sizeof(unsigned short), 0);
2229
    if (!array)
2230
        return -TARGET_EFAULT;
2231

    
2232
    for(i=0; i<nsems; i++) {
2233
        __put_user((*host_array)[i], &array[i]);
2234
    }
2235
    free(*host_array);
2236
    unlock_user(array, target_addr, 1);
2237

    
2238
    return 0;
2239
}
2240

    
2241
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2242
                                 union target_semun target_su)
2243
{
2244
    union semun arg;
2245
    struct semid_ds dsarg;
2246
    unsigned short *array = NULL;
2247
    struct seminfo seminfo;
2248
    abi_long ret = -TARGET_EINVAL;
2249
    abi_long err;
2250
    cmd &= 0xff;
2251

    
2252
    switch( cmd ) {
2253
        case GETVAL:
2254
        case SETVAL:
2255
            arg.val = tswapl(target_su.val);
2256
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2257
            target_su.val = tswapl(arg.val);
2258
            break;
2259
        case GETALL:
2260
        case SETALL:
2261
            err = target_to_host_semarray(semid, &array, target_su.array);
2262
            if (err)
2263
                return err;
2264
            arg.array = array;
2265
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2266
            err = host_to_target_semarray(semid, target_su.array, &array);
2267
            if (err)
2268
                return err;
2269
            break;
2270
        case IPC_STAT:
2271
        case IPC_SET:
2272
        case SEM_STAT:
2273
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2274
            if (err)
2275
                return err;
2276
            arg.buf = &dsarg;
2277
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2278
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2279
            if (err)
2280
                return err;
2281
            break;
2282
        case IPC_INFO:
2283
        case SEM_INFO:
2284
            arg.__buf = &seminfo;
2285
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2286
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2287
            if (err)
2288
                return err;
2289
            break;
2290
        case IPC_RMID:
2291
        case GETPID:
2292
        case GETNCNT:
2293
        case GETZCNT:
2294
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2295
            break;
2296
    }
2297

    
2298
    return ret;
2299
}
2300

    
2301
struct target_sembuf {
2302
    unsigned short sem_num;
2303
    short sem_op;
2304
    short sem_flg;
2305
};
2306

    
2307
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2308
                                             abi_ulong target_addr,
2309
                                             unsigned nsops)
2310
{
2311
    struct target_sembuf *target_sembuf;
2312
    int i;
2313

    
2314
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2315
                              nsops*sizeof(struct target_sembuf), 1);
2316
    if (!target_sembuf)
2317
        return -TARGET_EFAULT;
2318

    
2319
    for(i=0; i<nsops; i++) {
2320
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2321
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2322
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2323
    }
2324

    
2325
    unlock_user(target_sembuf, target_addr, 0);
2326

    
2327
    return 0;
2328
}
2329

    
2330
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2331
{
2332
    struct sembuf sops[nsops];
2333

    
2334
    if (target_to_host_sembuf(sops, ptr, nsops))
2335
        return -TARGET_EFAULT;
2336

    
2337
    return semop(semid, sops, nsops);
2338
}
2339

    
2340
struct target_msqid_ds
2341
{
2342
    struct target_ipc_perm msg_perm;
2343
    abi_ulong msg_stime;
2344
#if TARGET_ABI_BITS == 32
2345
    abi_ulong __unused1;
2346
#endif
2347
    abi_ulong msg_rtime;
2348
#if TARGET_ABI_BITS == 32
2349
    abi_ulong __unused2;
2350
#endif
2351
    abi_ulong msg_ctime;
2352
#if TARGET_ABI_BITS == 32
2353
    abi_ulong __unused3;
2354
#endif
2355
    abi_ulong __msg_cbytes;
2356
    abi_ulong msg_qnum;
2357
    abi_ulong msg_qbytes;
2358
    abi_ulong msg_lspid;
2359
    abi_ulong msg_lrpid;
2360
    abi_ulong __unused4;
2361
    abi_ulong __unused5;
2362
};
2363

    
2364
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2365
                                               abi_ulong target_addr)
2366
{
2367
    struct target_msqid_ds *target_md;
2368

    
2369
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2370
        return -TARGET_EFAULT;
2371
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2372
        return -TARGET_EFAULT;
2373
    host_md->msg_stime = tswapl(target_md->msg_stime);
2374
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2375
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2376
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2377
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2378
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2379
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2380
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2381
    unlock_user_struct(target_md, target_addr, 0);
2382
    return 0;
2383
}
2384

    
2385
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2386
                                               struct msqid_ds *host_md)
2387
{
2388
    struct target_msqid_ds *target_md;
2389

    
2390
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2391
        return -TARGET_EFAULT;
2392
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2393
        return -TARGET_EFAULT;
2394
    target_md->msg_stime = tswapl(host_md->msg_stime);
2395
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2396
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2397
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2398
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2399
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2400
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2401
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2402
    unlock_user_struct(target_md, target_addr, 1);
2403
    return 0;
2404
}
2405

    
2406
struct target_msginfo {
2407
    int msgpool;
2408
    int msgmap;
2409
    int msgmax;
2410
    int msgmnb;
2411
    int msgmni;
2412
    int msgssz;
2413
    int msgtql;
2414
    unsigned short int msgseg;
2415
};
2416

    
2417
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2418
                                              struct msginfo *host_msginfo)
2419
{
2420
    struct target_msginfo *target_msginfo;
2421
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2422
        return -TARGET_EFAULT;
2423
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2424
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2425
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2426
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2427
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2428
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2429
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2430
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2431
    unlock_user_struct(target_msginfo, target_addr, 1);
2432
    return 0;
2433
}
2434

    
2435
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2436
{
2437
    struct msqid_ds dsarg;
2438
    struct msginfo msginfo;
2439
    abi_long ret = -TARGET_EINVAL;
2440

    
2441
    cmd &= 0xff;
2442

    
2443
    switch (cmd) {
2444
    case IPC_STAT:
2445
    case IPC_SET:
2446
    case MSG_STAT:
2447
        if (target_to_host_msqid_ds(&dsarg,ptr))
2448
            return -TARGET_EFAULT;
2449
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2450
        if (host_to_target_msqid_ds(ptr,&dsarg))
2451
            return -TARGET_EFAULT;
2452
        break;
2453
    case IPC_RMID:
2454
        ret = get_errno(msgctl(msgid, cmd, NULL));
2455
        break;
2456
    case IPC_INFO:
2457
    case MSG_INFO:
2458
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2459
        if (host_to_target_msginfo(ptr, &msginfo))
2460
            return -TARGET_EFAULT;
2461
        break;
2462
    }
2463

    
2464
    return ret;
2465
}
2466

    
2467
struct target_msgbuf {
2468
    abi_long mtype;
2469
    char        mtext[1];
2470
};
2471

    
2472
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2473
                                 unsigned int msgsz, int msgflg)
2474
{
2475
    struct target_msgbuf *target_mb;
2476
    struct msgbuf *host_mb;
2477
    abi_long ret = 0;
2478

    
2479
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2480
        return -TARGET_EFAULT;
2481
    host_mb = malloc(msgsz+sizeof(long));
2482
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2483
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2484
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2485
    free(host_mb);
2486
    unlock_user_struct(target_mb, msgp, 0);
2487

    
2488
    return ret;
2489
}
2490

    
2491
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2492
                                 unsigned int msgsz, abi_long msgtyp,
2493
                                 int msgflg)
2494
{
2495
    struct target_msgbuf *target_mb;
2496
    char *target_mtext;
2497
    struct msgbuf *host_mb;
2498
    abi_long ret = 0;
2499

    
2500
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2501
        return -TARGET_EFAULT;
2502

    
2503
    host_mb = malloc(msgsz+sizeof(long));
2504
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2505

    
2506
    if (ret > 0) {
2507
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2508
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2509
        if (!target_mtext) {
2510
            ret = -TARGET_EFAULT;
2511
            goto end;
2512
        }
2513
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2514
        unlock_user(target_mtext, target_mtext_addr, ret);
2515
    }
2516

    
2517
    target_mb->mtype = tswapl(host_mb->mtype);
2518
    free(host_mb);
2519

    
2520
end:
2521
    if (target_mb)
2522
        unlock_user_struct(target_mb, msgp, 1);
2523
    return ret;
2524
}
2525

    
2526
struct target_shmid_ds
2527
{
2528
    struct target_ipc_perm shm_perm;
2529
    abi_ulong shm_segsz;
2530
    abi_ulong shm_atime;
2531
#if TARGET_ABI_BITS == 32
2532
    abi_ulong __unused1;
2533
#endif
2534
    abi_ulong shm_dtime;
2535
#if TARGET_ABI_BITS == 32
2536
    abi_ulong __unused2;
2537
#endif
2538
    abi_ulong shm_ctime;
2539
#if TARGET_ABI_BITS == 32
2540
    abi_ulong __unused3;
2541
#endif
2542
    int shm_cpid;
2543
    int shm_lpid;
2544
    abi_ulong shm_nattch;
2545
    unsigned long int __unused4;
2546
    unsigned long int __unused5;
2547
};
2548

    
2549
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2550
                                               abi_ulong target_addr)
2551
{
2552
    struct target_shmid_ds *target_sd;
2553

    
2554
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2555
        return -TARGET_EFAULT;
2556
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2557
        return -TARGET_EFAULT;
2558
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2559
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2560
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2561
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2562
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2563
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2564
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2565
    unlock_user_struct(target_sd, target_addr, 0);
2566
    return 0;
2567
}
2568

    
2569
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2570
                                               struct shmid_ds *host_sd)
2571
{
2572
    struct target_shmid_ds *target_sd;
2573

    
2574
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2575
        return -TARGET_EFAULT;
2576
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2577
        return -TARGET_EFAULT;
2578
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2579
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2580
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2581
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2582
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2583
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2584
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2585
    unlock_user_struct(target_sd, target_addr, 1);
2586
    return 0;
2587
}
2588

    
2589
struct  target_shminfo {
2590
    abi_ulong shmmax;
2591
    abi_ulong shmmin;
2592
    abi_ulong shmmni;
2593
    abi_ulong shmseg;
2594
    abi_ulong shmall;
2595
};
2596

    
2597
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2598
                                              struct shminfo *host_shminfo)
2599
{
2600
    struct target_shminfo *target_shminfo;
2601
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2602
        return -TARGET_EFAULT;
2603
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2604
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2605
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2606
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2607
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2608
    unlock_user_struct(target_shminfo, target_addr, 1);
2609
    return 0;
2610
}
2611

    
2612
struct target_shm_info {
2613
    int used_ids;
2614
    abi_ulong shm_tot;
2615
    abi_ulong shm_rss;
2616
    abi_ulong shm_swp;
2617
    abi_ulong swap_attempts;
2618
    abi_ulong swap_successes;
2619
};
2620

    
2621
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2622
                                               struct shm_info *host_shm_info)
2623
{
2624
    struct target_shm_info *target_shm_info;
2625
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2626
        return -TARGET_EFAULT;
2627
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2628
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2629
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2630
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2631
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2632
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2633
    unlock_user_struct(target_shm_info, target_addr, 1);
2634
    return 0;
2635
}
2636

    
2637
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2638
{
2639
    struct shmid_ds dsarg;
2640
    struct shminfo shminfo;
2641
    struct shm_info shm_info;
2642
    abi_long ret = -TARGET_EINVAL;
2643

    
2644
    cmd &= 0xff;
2645

    
2646
    switch(cmd) {
2647
    case IPC_STAT:
2648
    case IPC_SET:
2649
    case SHM_STAT:
2650
        if (target_to_host_shmid_ds(&dsarg, buf))
2651
            return -TARGET_EFAULT;
2652
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2653
        if (host_to_target_shmid_ds(buf, &dsarg))
2654
            return -TARGET_EFAULT;
2655
        break;
2656
    case IPC_INFO:
2657
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2658
        if (host_to_target_shminfo(buf, &shminfo))
2659
            return -TARGET_EFAULT;
2660
        break;
2661
    case SHM_INFO:
2662
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2663
        if (host_to_target_shm_info(buf, &shm_info))
2664
            return -TARGET_EFAULT;
2665
        break;
2666
    case IPC_RMID:
2667
    case SHM_LOCK:
2668
    case SHM_UNLOCK:
2669
        ret = get_errno(shmctl(shmid, cmd, NULL));
2670
        break;
2671
    }
2672

    
2673
    return ret;
2674
}
2675

    
2676
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2677
{
2678
    abi_long raddr;
2679
    void *host_raddr;
2680
    struct shmid_ds shm_info;
2681
    int i,ret;
2682

    
2683
    /* find out the length of the shared memory segment */
2684
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2685
    if (is_error(ret)) {
2686
        /* can't get length, bail out */
2687
        return ret;
2688
    }
2689

    
2690
    mmap_lock();
2691

    
2692
    if (shmaddr)
2693
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2694
    else {
2695
        abi_ulong mmap_start;
2696

    
2697
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2698

    
2699
        if (mmap_start == -1) {
2700
            errno = ENOMEM;
2701
            host_raddr = (void *)-1;
2702
        } else
2703
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2704
    }
2705

    
2706
    if (host_raddr == (void *)-1) {
2707
        mmap_unlock();
2708
        return get_errno((long)host_raddr);
2709
    }
2710
    raddr=h2g((unsigned long)host_raddr);
2711

    
2712
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2713
                   PAGE_VALID | PAGE_READ |
2714
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2715

    
2716
    for (i = 0; i < N_SHM_REGIONS; i++) {
2717
        if (shm_regions[i].start == 0) {
2718
            shm_regions[i].start = raddr;
2719
            shm_regions[i].size = shm_info.shm_segsz;
2720
            break;
2721
        }
2722
    }
2723

    
2724
    mmap_unlock();
2725
    return raddr;
2726

    
2727
}
2728

    
2729
static inline abi_long do_shmdt(abi_ulong shmaddr)
2730
{
2731
    int i;
2732

    
2733
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2734
        if (shm_regions[i].start == shmaddr) {
2735
            shm_regions[i].start = 0;
2736
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2737
            break;
2738
        }
2739
    }
2740

    
2741
    return get_errno(shmdt(g2h(shmaddr)));
2742
}
2743

    
2744
#ifdef TARGET_NR_ipc
2745
/* ??? This only works with linear mappings.  */
2746
/* do_ipc() must return target values and target errnos. */
2747
static abi_long do_ipc(unsigned int call, int first,
2748
                       int second, int third,
2749
                       abi_long ptr, abi_long fifth)
2750
{
2751
    int version;
2752
    abi_long ret = 0;
2753

    
2754
    version = call >> 16;
2755
    call &= 0xffff;
2756

    
2757
    switch (call) {
2758
    case IPCOP_semop:
2759
        ret = do_semop(first, ptr, second);
2760
        break;
2761

    
2762
    case IPCOP_semget:
2763
        ret = get_errno(semget(first, second, third));
2764
        break;
2765

    
2766
    case IPCOP_semctl:
2767
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2768
        break;
2769

    
2770
    case IPCOP_msgget:
2771
        ret = get_errno(msgget(first, second));
2772
        break;
2773

    
2774
    case IPCOP_msgsnd:
2775
        ret = do_msgsnd(first, ptr, second, third);
2776
        break;
2777

    
2778
    case IPCOP_msgctl:
2779
        ret = do_msgctl(first, second, ptr);
2780
        break;
2781

    
2782
    case IPCOP_msgrcv:
2783
        switch (version) {
2784
        case 0:
2785
            {
2786
                struct target_ipc_kludge {
2787
                    abi_long msgp;
2788
                    abi_long msgtyp;
2789
                } *tmp;
2790

    
2791
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2792
                    ret = -TARGET_EFAULT;
2793
                    break;
2794
                }
2795

    
2796
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2797

    
2798
                unlock_user_struct(tmp, ptr, 0);
2799
                break;
2800
            }
2801
        default:
2802
            ret = do_msgrcv(first, ptr, second, fifth, third);
2803
        }
2804
        break;
2805

    
2806
    case IPCOP_shmat:
2807
        switch (version) {
2808
        default:
2809
        {
2810
            abi_ulong raddr;
2811
            raddr = do_shmat(first, ptr, second);
2812
            if (is_error(raddr))
2813
                return get_errno(raddr);
2814
            if (put_user_ual(raddr, third))
2815
                return -TARGET_EFAULT;
2816
            break;
2817
        }
2818
        case 1:
2819
            ret = -TARGET_EINVAL;
2820
            break;
2821
        }
2822
        break;
2823
    case IPCOP_shmdt:
2824
        ret = do_shmdt(ptr);
2825
        break;
2826

    
2827
    case IPCOP_shmget:
2828
        /* IPC_* flag values are the same on all linux platforms */
2829
        ret = get_errno(shmget(first, second, third));
2830
        break;
2831

    
2832
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2833
    case IPCOP_shmctl:
2834
        ret = do_shmctl(first, second, third);
2835
        break;
2836
    default:
2837
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2838
        ret = -TARGET_ENOSYS;
2839
        break;
2840
    }
2841
    return ret;
2842
}
2843
#endif
2844

    
2845
/* kernel structure types definitions */
2846
#define IFNAMSIZ        16
2847

    
2848
#define STRUCT(name, ...) STRUCT_ ## name,
2849
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2850
enum {
2851
#include "syscall_types.h"
2852
};
2853
#undef STRUCT
2854
#undef STRUCT_SPECIAL
2855

    
2856
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2857
#define STRUCT_SPECIAL(name)
2858
#include "syscall_types.h"
2859
#undef STRUCT
2860
#undef STRUCT_SPECIAL
2861

    
2862
typedef struct IOCTLEntry {
2863
    unsigned int target_cmd;
2864
    unsigned int host_cmd;
2865
    const char *name;
2866
    int access;
2867
    const argtype arg_type[5];
2868
} IOCTLEntry;
2869

    
2870
#define IOC_R 0x0001
2871
#define IOC_W 0x0002
2872
#define IOC_RW (IOC_R | IOC_W)
2873

    
2874
#define MAX_STRUCT_SIZE 4096
2875

    
2876
static IOCTLEntry ioctl_entries[] = {
2877
#define IOCTL(cmd, access, ...) \
2878
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2879
#include "ioctls.h"
2880
    { 0, 0, },
2881
};
2882

    
2883
/* ??? Implement proper locking for ioctls.  */
2884
/* do_ioctl() Must return target values and target errnos. */
2885
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2886
{
2887
    const IOCTLEntry *ie;
2888
    const argtype *arg_type;
2889
    abi_long ret;
2890
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2891
    int target_size;
2892
    void *argptr;
2893

    
2894
    ie = ioctl_entries;
2895
    for(;;) {
2896
        if (ie->target_cmd == 0) {
2897
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2898
            return -TARGET_ENOSYS;
2899
        }
2900
        if (ie->target_cmd == cmd)
2901
            break;
2902
        ie++;
2903
    }
2904
    arg_type = ie->arg_type;
2905
#if defined(DEBUG)
2906
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2907
#endif
2908
    switch(arg_type[0]) {
2909
    case TYPE_NULL:
2910
        /* no argument */
2911
        ret = get_errno(ioctl(fd, ie->host_cmd));
2912
        break;
2913
    case TYPE_PTRVOID:
2914
    case TYPE_INT:
2915
        /* int argment */
2916
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2917
        break;
2918
    case TYPE_PTR:
2919
        arg_type++;
2920
        target_size = thunk_type_size(arg_type, 0);
2921
        switch(ie->access) {
2922
        case IOC_R:
2923
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2924
            if (!is_error(ret)) {
2925
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2926
                if (!argptr)
2927
                    return -TARGET_EFAULT;
2928
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2929
                unlock_user(argptr, arg, target_size);
2930
            }
2931
            break;
2932
        case IOC_W:
2933
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2934
            if (!argptr)
2935
                return -TARGET_EFAULT;
2936
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2937
            unlock_user(argptr, arg, 0);
2938
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2939
            break;
2940
        default:
2941
        case IOC_RW:
2942
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2943
            if (!argptr)
2944
                return -TARGET_EFAULT;
2945
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2946
            unlock_user(argptr, arg, 0);
2947
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2948
            if (!is_error(ret)) {
2949
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2950
                if (!argptr)
2951
                    return -TARGET_EFAULT;
2952
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2953
                unlock_user(argptr, arg, target_size);
2954
            }
2955
            break;
2956
        }
2957
        break;
2958
    default:
2959
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2960
                 (long)cmd, arg_type[0]);
2961
        ret = -TARGET_ENOSYS;
2962
        break;
2963
    }
2964
    return ret;
2965
}
2966

    
2967
static const bitmask_transtbl iflag_tbl[] = {
2968
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2969
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2970
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2971
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2972
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2973
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2974
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2975
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2976
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2977
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2978
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2979
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2980
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2981
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2982
        { 0, 0, 0, 0 }
2983
};
2984

    
2985
static const bitmask_transtbl oflag_tbl[] = {
2986
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2987
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2988
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2989
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2990
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2991
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2992
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2993
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2994
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2995
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2996
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2997
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2998
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2999
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3000
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3001
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3002
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3003
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3004
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3005
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3006
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3007
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3008
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3009
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3010
        { 0, 0, 0, 0 }
3011
};
3012

    
3013
static const bitmask_transtbl cflag_tbl[] = {
3014
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3015
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3016
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3017
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3018
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3019
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3020
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3021
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3022
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3023
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3024
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3025
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3026
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3027
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3028
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3029
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3030
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3031
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3032
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3033
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3034
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3035
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3036
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3037
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3038
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3039
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3040
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3041
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3042
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3043
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3044
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3045
        { 0, 0, 0, 0 }
3046
};
3047

    
3048
static const bitmask_transtbl lflag_tbl[] = {
3049
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3050
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3051
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3052
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3053
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3054
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3055
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3056
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3057
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3058
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3059
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3060
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3061
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3062
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3063
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3064
        { 0, 0, 0, 0 }
3065
};
3066

    
3067
static void target_to_host_termios (void *dst, const void *src)
3068
{
3069
    struct host_termios *host = dst;
3070
    const struct target_termios *target = src;
3071

    
3072
    host->c_iflag =
3073
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3074
    host->c_oflag =
3075
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3076
    host->c_cflag =
3077
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3078
    host->c_lflag =
3079
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3080
    host->c_line = target->c_line;
3081

    
3082
    memset(host->c_cc, 0, sizeof(host->c_cc));
3083
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3084
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3085
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3086
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3087
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3088
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3089
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3090
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3091
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3092
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3093
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3094
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3095
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3096
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3097
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3098
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3099
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3100
}
3101

    
3102
static void host_to_target_termios (void *dst, const void *src)
3103
{
3104
    struct target_termios *target = dst;
3105
    const struct host_termios *host = src;
3106

    
3107
    target->c_iflag =
3108
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3109
    target->c_oflag =
3110
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3111
    target->c_cflag =
3112
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3113
    target->c_lflag =
3114
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3115
    target->c_line = host->c_line;
3116

    
3117
    memset(target->c_cc, 0, sizeof(target->c_cc));
3118
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3119
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3120
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3121
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3122
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3123
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3124
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3125
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3126
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3127
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3128
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3129
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3130
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3131
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3132
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3133
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3134
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3135
}
3136

    
3137
static const StructEntry struct_termios_def = {
3138
    .convert = { host_to_target_termios, target_to_host_termios },
3139
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3140
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3141
};
3142

    
3143
static bitmask_transtbl mmap_flags_tbl[] = {
3144
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3145
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3146
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3147
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3148
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3149
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3150
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3151
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3152
        { 0, 0, 0, 0 }
3153
};
3154

    
3155
#if defined(TARGET_I386)
3156

    
3157
/* NOTE: there is really one LDT for all the threads */
3158
static uint8_t *ldt_table;
3159

    
3160
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3161
{
3162
    int size;
3163
    void *p;
3164

    
3165
    if (!ldt_table)
3166
        return 0;
3167
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3168
    if (size > bytecount)
3169
        size = bytecount;
3170
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3171
    if (!p)
3172
        return -TARGET_EFAULT;
3173
    /* ??? Should this by byteswapped?  */
3174
    memcpy(p, ldt_table, size);
3175
    unlock_user(p, ptr, size);
3176
    return size;
3177
}
3178

    
3179
/* XXX: add locking support */
3180
static abi_long write_ldt(CPUX86State *env,
3181
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3182
{
3183
    struct target_modify_ldt_ldt_s ldt_info;
3184
    struct target_modify_ldt_ldt_s *target_ldt_info;
3185
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3186
    int seg_not_present, useable, lm;
3187
    uint32_t *lp, entry_1, entry_2;
3188

    
3189
    if (bytecount != sizeof(ldt_info))
3190
        return -TARGET_EINVAL;
3191
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3192
        return -TARGET_EFAULT;
3193
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3194
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3195
    ldt_info.limit = tswap32(target_ldt_info->limit);
3196
    ldt_info.flags = tswap32(target_ldt_info->flags);
3197
    unlock_user_struct(target_ldt_info, ptr, 0);
3198

    
3199
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3200
        return -TARGET_EINVAL;
3201
    seg_32bit = ldt_info.flags & 1;
3202
    contents = (ldt_info.flags >> 1) & 3;
3203
    read_exec_only = (ldt_info.flags >> 3) & 1;
3204
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3205
    seg_not_present = (ldt_info.flags >> 5) & 1;
3206
    useable = (ldt_info.flags >> 6) & 1;
3207
#ifdef TARGET_ABI32
3208
    lm = 0;
3209
#else
3210
    lm = (ldt_info.flags >> 7) & 1;
3211
#endif
3212
    if (contents == 3) {
3213
        if (oldmode)
3214
            return -TARGET_EINVAL;
3215
        if (seg_not_present == 0)
3216
            return -TARGET_EINVAL;
3217
    }
3218
    /* allocate the LDT */
3219
    if (!ldt_table) {
3220
        env->ldt.base = target_mmap(0,
3221
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3222
                                    PROT_READ|PROT_WRITE,
3223
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3224
        if (env->ldt.base == -1)
3225
            return -TARGET_ENOMEM;
3226
        memset(g2h(env->ldt.base), 0,
3227
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3228
        env->ldt.limit = 0xffff;
3229
        ldt_table = g2h(env->ldt.base);
3230
    }
3231

    
3232
    /* NOTE: same code as Linux kernel */
3233
    /* Allow LDTs to be cleared by the user. */
3234
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3235
        if (oldmode ||
3236
            (contents == 0                &&
3237
             read_exec_only == 1        &&
3238
             seg_32bit == 0                &&
3239
             limit_in_pages == 0        &&
3240
             seg_not_present == 1        &&
3241
             useable == 0 )) {
3242
            entry_1 = 0;
3243
            entry_2 = 0;
3244
            goto install;
3245
        }
3246
    }
3247

    
3248
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3249
        (ldt_info.limit & 0x0ffff);
3250
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3251
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3252
        (ldt_info.limit & 0xf0000) |
3253
        ((read_exec_only ^ 1) << 9) |
3254
        (contents << 10) |
3255
        ((seg_not_present ^ 1) << 15) |
3256
        (seg_32bit << 22) |
3257
        (limit_in_pages << 23) |
3258
        (lm << 21) |
3259
        0x7000;
3260
    if (!oldmode)
3261
        entry_2 |= (useable << 20);
3262

    
3263
    /* Install the new entry ...  */
3264
install:
3265
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3266
    lp[0] = tswap32(entry_1);
3267
    lp[1] = tswap32(entry_2);
3268
    return 0;
3269
}
3270

    
3271
/* specific and weird i386 syscalls */
3272
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3273
                              unsigned long bytecount)
3274
{
3275
    abi_long ret;
3276

    
3277
    switch (func) {
3278
    case 0:
3279
        ret = read_ldt(ptr, bytecount);
3280
        break;
3281
    case 1:
3282
        ret = write_ldt(env, ptr, bytecount, 1);
3283
        break;
3284
    case 0x11:
3285
        ret = write_ldt(env, ptr, bytecount, 0);
3286
        break;
3287
    default:
3288
        ret = -TARGET_ENOSYS;
3289
        break;
3290
    }
3291
    return ret;
3292
}
3293

    
3294
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3295
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3296
{
3297
    uint64_t *gdt_table = g2h(env->gdt.base);
3298
    struct target_modify_ldt_ldt_s ldt_info;
3299
    struct target_modify_ldt_ldt_s *target_ldt_info;
3300
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3301
    int seg_not_present, useable, lm;
3302
    uint32_t *lp, entry_1, entry_2;
3303
    int i;
3304

    
3305
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3306
    if (!target_ldt_info)
3307
        return -TARGET_EFAULT;
3308
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3309
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3310
    ldt_info.limit = tswap32(target_ldt_info->limit);
3311
    ldt_info.flags = tswap32(target_ldt_info->flags);
3312
    if (ldt_info.entry_number == -1) {
3313
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3314
            if (gdt_table[i] == 0) {
3315
                ldt_info.entry_number = i;
3316
                target_ldt_info->entry_number = tswap32(i);
3317
                break;
3318
            }
3319
        }
3320
    }
3321
    unlock_user_struct(target_ldt_info, ptr, 1);
3322

    
3323
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3324
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3325
           return -TARGET_EINVAL;
3326
    seg_32bit = ldt_info.flags & 1;
3327
    contents = (ldt_info.flags >> 1) & 3;
3328
    read_exec_only = (ldt_info.flags >> 3) & 1;
3329
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3330
    seg_not_present = (ldt_info.flags >> 5) & 1;
3331
    useable = (ldt_info.flags >> 6) & 1;
3332
#ifdef TARGET_ABI32
3333
    lm = 0;
3334
#else
3335
    lm = (ldt_info.flags >> 7) & 1;
3336
#endif
3337

    
3338
    if (contents == 3) {
3339
        if (seg_not_present == 0)
3340
            return -TARGET_EINVAL;
3341
    }
3342

    
3343
    /* NOTE: same code as Linux kernel */
3344
    /* Allow LDTs to be cleared by the user. */
3345
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3346
        if ((contents == 0             &&
3347
             read_exec_only == 1       &&
3348
             seg_32bit == 0            &&
3349
             limit_in_pages == 0       &&
3350
             seg_not_present == 1      &&
3351
             useable == 0 )) {
3352
            entry_1 = 0;
3353
            entry_2 = 0;
3354
            goto install;
3355
        }
3356
    }
3357

    
3358
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3359
        (ldt_info.limit & 0x0ffff);
3360
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3361
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3362
        (ldt_info.limit & 0xf0000) |
3363
        ((read_exec_only ^ 1) << 9) |
3364
        (contents << 10) |
3365
        ((seg_not_present ^ 1) << 15) |
3366
        (seg_32bit << 22) |
3367
        (limit_in_pages << 23) |
3368
        (useable << 20) |
3369
        (lm << 21) |
3370
        0x7000;
3371

    
3372
    /* Install the new entry ...  */
3373
install:
3374
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3375
    lp[0] = tswap32(entry_1);
3376
    lp[1] = tswap32(entry_2);
3377
    return 0;
3378
}
3379

    
3380
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3381
{
3382
    struct target_modify_ldt_ldt_s *target_ldt_info;
3383
    uint64_t *gdt_table = g2h(env->gdt.base);
3384
    uint32_t base_addr, limit, flags;
3385
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3386
    int seg_not_present, useable, lm;
3387
    uint32_t *lp, entry_1, entry_2;
3388

    
3389
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3390
    if (!target_ldt_info)
3391
        return -TARGET_EFAULT;
3392
    idx = tswap32(target_ldt_info->entry_number);
3393
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3394
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3395
        unlock_user_struct(target_ldt_info, ptr, 1);
3396
        return -TARGET_EINVAL;
3397
    }
3398
    lp = (uint32_t *)(gdt_table + idx);
3399
    entry_1 = tswap32(lp[0]);
3400
    entry_2 = tswap32(lp[1]);
3401
    
3402
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3403
    contents = (entry_2 >> 10) & 3;
3404
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3405
    seg_32bit = (entry_2 >> 22) & 1;
3406
    limit_in_pages = (entry_2 >> 23) & 1;
3407
    useable = (entry_2 >> 20) & 1;
3408
#ifdef TARGET_ABI32
3409
    lm = 0;
3410
#else
3411
    lm = (entry_2 >> 21) & 1;
3412
#endif
3413
    flags = (seg_32bit << 0) | (contents << 1) |
3414
        (read_exec_only << 3) | (limit_in_pages << 4) |
3415
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3416
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3417
    base_addr = (entry_1 >> 16) | 
3418
        (entry_2 & 0xff000000) | 
3419
        ((entry_2 & 0xff) << 16);
3420
    target_ldt_info->base_addr = tswapl(base_addr);
3421
    target_ldt_info->limit = tswap32(limit);
3422
    target_ldt_info->flags = tswap32(flags);
3423
    unlock_user_struct(target_ldt_info, ptr, 1);
3424
    return 0;
3425
}
3426
#endif /* TARGET_I386 && TARGET_ABI32 */
3427

    
3428
#ifndef TARGET_ABI32
3429
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3430
{
3431
    abi_long ret;
3432
    abi_ulong val;
3433
    int idx;
3434
    
3435
    switch(code) {
3436
    case TARGET_ARCH_SET_GS:
3437
    case TARGET_ARCH_SET_FS:
3438
        if (code == TARGET_ARCH_SET_GS)
3439
            idx = R_GS;
3440
        else
3441
            idx = R_FS;
3442
        cpu_x86_load_seg(env, idx, 0);
3443
        env->segs[idx].base = addr;
3444
        break;
3445
    case TARGET_ARCH_GET_GS:
3446
    case TARGET_ARCH_GET_FS:
3447
        if (code == TARGET_ARCH_GET_GS)
3448
            idx = R_GS;
3449
        else
3450
            idx = R_FS;
3451
        val = env->segs[idx].base;
3452
        if (put_user(val, addr, abi_ulong))
3453
            return -TARGET_EFAULT;
3454
        break;
3455
    default:
3456
        ret = -TARGET_EINVAL;
3457
        break;
3458
    }
3459
    return 0;
3460
}
3461
#endif
3462

    
3463
#endif /* defined(TARGET_I386) */
3464

    
3465
#if defined(CONFIG_USE_NPTL)
3466

    
3467
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3468

    
3469
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3470
typedef struct {
3471
    CPUState *env;
3472
    pthread_mutex_t mutex;
3473
    pthread_cond_t cond;
3474
    pthread_t thread;
3475
    uint32_t tid;
3476
    abi_ulong child_tidptr;
3477
    abi_ulong parent_tidptr;
3478
    sigset_t sigmask;
3479
} new_thread_info;
3480

    
3481
static void *clone_func(void *arg)
3482
{
3483
    new_thread_info *info = arg;
3484
    CPUState *env;
3485
    TaskState *ts;
3486

    
3487
    env = info->env;
3488
    thread_env = env;
3489
    ts = (TaskState *)thread_env->opaque;
3490
    info->tid = gettid();
3491
    env->host_tid = info->tid;
3492
    task_settid(ts);
3493
    if (info->child_tidptr)
3494
        put_user_u32(info->tid, info->child_tidptr);
3495
    if (info->parent_tidptr)
3496
        put_user_u32(info->tid, info->parent_tidptr);
3497
    /* Enable signals.  */
3498
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3499
    /* Signal to the parent that we're ready.  */
3500
    pthread_mutex_lock(&info->mutex);
3501
    pthread_cond_broadcast(&info->cond);
3502
    pthread_mutex_unlock(&info->mutex);
3503
    /* Wait until the parent has finshed initializing the tls state.  */
3504
    pthread_mutex_lock(&clone_lock);
3505
    pthread_mutex_unlock(&clone_lock);
3506
    cpu_loop(env);
3507
    /* never exits */
3508
    return NULL;
3509
}
3510
#else
3511
/* this stack is the equivalent of the kernel stack associated with a
3512
   thread/process */
3513
#define NEW_STACK_SIZE 8192
3514

    
3515
static int clone_func(void *arg)
3516
{
3517
    CPUState *env = arg;
3518
    cpu_loop(env);
3519
    /* never exits */
3520
    return 0;
3521
}
3522
#endif
3523

    
3524
/* do_fork() Must return host values and target errnos (unlike most
3525
   do_*() functions). */
3526
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3527
                   abi_ulong parent_tidptr, target_ulong newtls,
3528
                   abi_ulong child_tidptr)
3529
{
3530
    int ret;
3531
    TaskState *ts;
3532
    uint8_t *new_stack;
3533
    CPUState *new_env;
3534
#if defined(CONFIG_USE_NPTL)
3535
    unsigned int nptl_flags;
3536
    sigset_t sigmask;
3537
#endif
3538

    
3539
    /* Emulate vfork() with fork() */
3540
    if (flags & CLONE_VFORK)
3541
        flags &= ~(CLONE_VFORK | CLONE_VM);
3542

    
3543
    if (flags & CLONE_VM) {
3544
        TaskState *parent_ts = (TaskState *)env->opaque;
3545
#if defined(CONFIG_USE_NPTL)
3546
        new_thread_info info;
3547
        pthread_attr_t attr;
3548
#endif
3549
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3550
        init_task_state(ts);
3551
        new_stack = ts->stack;
3552
        /* we create a new CPU instance. */
3553
        new_env = cpu_copy(env);
3554
        /* Init regs that differ from the parent.  */
3555
        cpu_clone_regs(new_env, newsp);
3556
        new_env->opaque = ts;
3557
        ts->bprm = parent_ts->bprm;
3558
        ts->info = parent_ts->info;
3559
#if defined(CONFIG_USE_NPTL)
3560
        nptl_flags = flags;
3561
        flags &= ~CLONE_NPTL_FLAGS2;
3562

    
3563
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3564
            ts->child_tidptr = child_tidptr;
3565
        }
3566

    
3567
        if (nptl_flags & CLONE_SETTLS)
3568
            cpu_set_tls (new_env, newtls);
3569

    
3570
        /* Grab a mutex so that thread setup appears atomic.  */
3571
        pthread_mutex_lock(&clone_lock);
3572

    
3573
        memset(&info, 0, sizeof(info));
3574
        pthread_mutex_init(&info.mutex, NULL);
3575
        pthread_mutex_lock(&info.mutex);
3576
        pthread_cond_init(&info.cond, NULL);
3577
        info.env = new_env;
3578
        if (nptl_flags & CLONE_CHILD_SETTID)
3579
            info.child_tidptr = child_tidptr;
3580
        if (nptl_flags & CLONE_PARENT_SETTID)
3581
            info.parent_tidptr = parent_tidptr;
3582

    
3583
        ret = pthread_attr_init(&attr);
3584
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3585
        /* It is not safe to deliver signals until the child has finished
3586
           initializing, so temporarily block all signals.  */
3587
        sigfillset(&sigmask);
3588
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3589

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

    
3593
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3594
        pthread_attr_destroy(&attr);
3595
        if (ret == 0) {
3596
            /* Wait for the child to initialize.  */
3597
            pthread_cond_wait(&info.cond, &info.mutex);
3598
            ret = info.tid;
3599
            if (flags & CLONE_PARENT_SETTID)
3600
                put_user_u32(ret, parent_tidptr);
3601
        } else {
3602
            ret = -1;
3603
        }
3604
        pthread_mutex_unlock(&info.mutex);
3605
        pthread_cond_destroy(&info.cond);
3606
        pthread_mutex_destroy(&info.mutex);
3607
        pthread_mutex_unlock(&clone_lock);
3608
#else
3609
        if (flags & CLONE_NPTL_FLAGS2)
3610
            return -EINVAL;
3611
        /* This is probably going to die very quickly, but do it anyway.  */
3612
#ifdef __ia64__
3613
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3614
#else
3615
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3616
#endif
3617
#endif
3618
    } else {
3619
        /* if no CLONE_VM, we consider it is a fork */
3620
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3621
            return -EINVAL;
3622
        fork_start();
3623
        ret = fork();
3624
        if (ret == 0) {
3625
            /* Child Process.  */
3626
            cpu_clone_regs(env, newsp);
3627
            fork_end(1);
3628
#if defined(CONFIG_USE_NPTL)
3629
            /* There is a race condition here.  The parent process could
3630
               theoretically read the TID in the child process before the child
3631
               tid is set.  This would require using either ptrace
3632
               (not implemented) or having *_tidptr to point at a shared memory
3633
               mapping.  We can't repeat the spinlock hack used above because
3634
               the child process gets its own copy of the lock.  */
3635
            if (flags & CLONE_CHILD_SETTID)
3636
                put_user_u32(gettid(), child_tidptr);
3637
            if (flags & CLONE_PARENT_SETTID)
3638
                put_user_u32(gettid(), parent_tidptr);
3639
            ts = (TaskState *)env->opaque;
3640
            if (flags & CLONE_SETTLS)
3641
                cpu_set_tls (env, newtls);
3642
            if (flags & CLONE_CHILD_CLEARTID)
3643
                ts->child_tidptr = child_tidptr;
3644
#endif
3645
        } else {
3646
            fork_end(0);
3647
        }
3648
    }
3649
    return ret;
3650
}
3651

    
3652
/* warning : doesn't handle linux specific flags... */
3653
static int target_to_host_fcntl_cmd(int cmd)
3654
{
3655
    switch(cmd) {
3656
        case TARGET_F_DUPFD:
3657
        case TARGET_F_GETFD:
3658
        case TARGET_F_SETFD:
3659
        case TARGET_F_GETFL:
3660
        case TARGET_F_SETFL:
3661
            return cmd;
3662
        case TARGET_F_GETLK:
3663
            return F_GETLK;
3664
        case TARGET_F_SETLK:
3665
            return F_SETLK;
3666
        case TARGET_F_SETLKW:
3667
            return F_SETLKW;
3668
        case TARGET_F_GETOWN:
3669
            return F_GETOWN;
3670
        case TARGET_F_SETOWN:
3671
            return F_SETOWN;
3672
        case TARGET_F_GETSIG:
3673
            return F_GETSIG;
3674
        case TARGET_F_SETSIG:
3675
            return F_SETSIG;
3676
#if TARGET_ABI_BITS == 32
3677
        case TARGET_F_GETLK64:
3678
            return F_GETLK64;
3679
        case TARGET_F_SETLK64:
3680
            return F_SETLK64;
3681
        case TARGET_F_SETLKW64:
3682
            return F_SETLKW64;
3683
#endif
3684
        case TARGET_F_SETLEASE:
3685
            return F_SETLEASE;
3686
        case TARGET_F_GETLEASE:
3687
            return F_GETLEASE;
3688
#ifdef F_DUPFD_CLOEXEC
3689
        case TARGET_F_DUPFD_CLOEXEC:
3690
            return F_DUPFD_CLOEXEC;
3691
#endif
3692
        case TARGET_F_NOTIFY:
3693
            return F_NOTIFY;
3694
        default:
3695
            return -TARGET_EINVAL;
3696
    }
3697
    return -TARGET_EINVAL;
3698
}
3699

    
3700
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3701
{
3702
    struct flock fl;
3703
    struct target_flock *target_fl;
3704
    struct flock64 fl64;
3705
    struct target_flock64 *target_fl64;
3706
    abi_long ret;
3707
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3708

    
3709
    if (host_cmd == -TARGET_EINVAL)
3710
            return host_cmd;
3711

    
3712
    switch(cmd) {
3713
    case TARGET_F_GETLK:
3714
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3715
            return -TARGET_EFAULT;
3716
        fl.l_type = tswap16(target_fl->l_type);
3717
        fl.l_whence = tswap16(target_fl->l_whence);
3718
        fl.l_start = tswapl(target_fl->l_start);
3719
        fl.l_len = tswapl(target_fl->l_len);
3720
        fl.l_pid = tswap32(target_fl->l_pid);
3721
        unlock_user_struct(target_fl, arg, 0);
3722
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3723
        if (ret == 0) {
3724
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3725
                return -TARGET_EFAULT;
3726
            target_fl->l_type = tswap16(fl.l_type);
3727
            target_fl->l_whence = tswap16(fl.l_whence);
3728
            target_fl->l_start = tswapl(fl.l_start);
3729
            target_fl->l_len = tswapl(fl.l_len);
3730
            target_fl->l_pid = tswap32(fl.l_pid);
3731
            unlock_user_struct(target_fl, arg, 1);
3732
        }
3733
        break;
3734

    
3735
    case TARGET_F_SETLK:
3736
    case TARGET_F_SETLKW:
3737
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3738
            return -TARGET_EFAULT;
3739
        fl.l_type = tswap16(target_fl->l_type);
3740
        fl.l_whence = tswap16(target_fl->l_whence);
3741
        fl.l_start = tswapl(target_fl->l_start);
3742
        fl.l_len = tswapl(target_fl->l_len);
3743
        fl.l_pid = tswap32(target_fl->l_pid);
3744
        unlock_user_struct(target_fl, arg, 0);
3745
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3746
        break;
3747

    
3748
    case TARGET_F_GETLK64:
3749
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3750
            return -TARGET_EFAULT;
3751
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3752
        fl64.l_whence = tswap16(target_fl64->l_whence);
3753
        fl64.l_start = tswapl(target_fl64->l_start);
3754
        fl64.l_len = tswapl(target_fl64->l_len);
3755
        fl64.l_pid = tswap32(target_fl64->l_pid);
3756
        unlock_user_struct(target_fl64, arg, 0);
3757
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3758
        if (ret == 0) {
3759
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3760
                return -TARGET_EFAULT;
3761
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3762
            target_fl64->l_whence = tswap16(fl64.l_whence);
3763
            target_fl64->l_start = tswapl(fl64.l_start);
3764
            target_fl64->l_len = tswapl(fl64.l_len);
3765
            target_fl64->l_pid = tswap32(fl64.l_pid);
3766
            unlock_user_struct(target_fl64, arg, 1);
3767
        }
3768
        break;
3769
    case TARGET_F_SETLK64:
3770
    case TARGET_F_SETLKW64:
3771
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3772
            return -TARGET_EFAULT;
3773
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3774
        fl64.l_whence = tswap16(target_fl64->l_whence);
3775
        fl64.l_start = tswapl(target_fl64->l_start);
3776
        fl64.l_len = tswapl(target_fl64->l_len);
3777
        fl64.l_pid = tswap32(target_fl64->l_pid);
3778
        unlock_user_struct(target_fl64, arg, 0);
3779
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3780
        break;
3781

    
3782
    case TARGET_F_GETFL:
3783
        ret = get_errno(fcntl(fd, host_cmd, arg));
3784
        if (ret >= 0) {
3785
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3786
        }
3787
        break;
3788

    
3789
    case TARGET_F_SETFL:
3790
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3791
        break;
3792

    
3793
    case TARGET_F_SETOWN:
3794
    case TARGET_F_GETOWN:
3795
    case TARGET_F_SETSIG:
3796
    case TARGET_F_GETSIG:
3797
    case TARGET_F_SETLEASE:
3798
    case TARGET_F_GETLEASE:
3799
        ret = get_errno(fcntl(fd, host_cmd, arg));
3800
        break;
3801

    
3802
    default:
3803
        ret = get_errno(fcntl(fd, cmd, arg));
3804
        break;
3805
    }
3806
    return ret;
3807
}
3808

    
3809
#ifdef USE_UID16
3810

    
3811
static inline int high2lowuid(int uid)
3812
{
3813
    if (uid > 65535)
3814
        return 65534;
3815
    else
3816
        return uid;
3817
}
3818

    
3819
static inline int high2lowgid(int gid)
3820
{
3821
    if (gid > 65535)
3822
        return 65534;
3823
    else
3824
        return gid;
3825
}
3826

    
3827
static inline int low2highuid(int uid)
3828
{
3829
    if ((int16_t)uid == -1)
3830
        return -1;
3831
    else
3832
        return uid;
3833
}
3834

    
3835
static inline int low2highgid(int gid)
3836
{
3837
    if ((int16_t)gid == -1)
3838
        return -1;
3839
    else
3840
        return gid;
3841
}
3842

    
3843
#endif /* USE_UID16 */
3844

    
3845
void syscall_init(void)
3846
{
3847
    IOCTLEntry *ie;
3848
    const argtype *arg_type;
3849
    int size;
3850
    int i;
3851

    
3852
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3853
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3854
#include "syscall_types.h"
3855
#undef STRUCT
3856
#undef STRUCT_SPECIAL
3857

    
3858
    /* we patch the ioctl size if necessary. We rely on the fact that
3859
       no ioctl has all the bits at '1' in the size field */
3860
    ie = ioctl_entries;
3861
    while (ie->target_cmd != 0) {
3862
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3863
            TARGET_IOC_SIZEMASK) {
3864
            arg_type = ie->arg_type;
3865
            if (arg_type[0] != TYPE_PTR) {
3866
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3867
                        ie->target_cmd);
3868
                exit(1);
3869
            }
3870
            arg_type++;
3871
            size = thunk_type_size(arg_type, 0);
3872
            ie->target_cmd = (ie->target_cmd &
3873
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3874
                (size << TARGET_IOC_SIZESHIFT);
3875
        }
3876

    
3877
        /* Build target_to_host_errno_table[] table from
3878
         * host_to_target_errno_table[]. */
3879
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3880
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3881

    
3882
        /* automatic consistency check if same arch */
3883
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3884
    (defined(__x86_64__) && defined(TARGET_X86_64))
3885
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3886
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3887
                    ie->name, ie->target_cmd, ie->host_cmd);
3888
        }
3889
#endif
3890
        ie++;
3891
    }
3892
}
3893

    
3894
#if TARGET_ABI_BITS == 32
3895
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3896
{
3897
#ifdef TARGET_WORDS_BIGENDIAN
3898
    return ((uint64_t)word0 << 32) | word1;
3899
#else
3900
    return ((uint64_t)word1 << 32) | word0;
3901
#endif
3902
}
3903
#else /* TARGET_ABI_BITS == 32 */
3904
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3905
{
3906
    return word0;
3907
}
3908
#endif /* TARGET_ABI_BITS != 32 */
3909

    
3910
#ifdef TARGET_NR_truncate64
3911
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3912
                                         abi_long arg2,
3913
                                         abi_long arg3,
3914
                                         abi_long arg4)
3915
{
3916
#ifdef TARGET_ARM
3917
    if (((CPUARMState *)cpu_env)->eabi)
3918
      {
3919
        arg2 = arg3;
3920
        arg3 = arg4;
3921
      }
3922
#endif
3923
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3924
}
3925
#endif
3926

    
3927
#ifdef TARGET_NR_ftruncate64
3928
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3929
                                          abi_long arg2,
3930
                                          abi_long arg3,
3931
                                          abi_long arg4)
3932
{
3933
#ifdef TARGET_ARM
3934
    if (((CPUARMState *)cpu_env)->eabi)
3935
      {
3936
        arg2 = arg3;
3937
        arg3 = arg4;
3938
      }
3939
#endif
3940
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3941
}
3942
#endif
3943

    
3944
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3945
                                               abi_ulong target_addr)
3946
{
3947
    struct target_timespec *target_ts;
3948

    
3949
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3950
        return -TARGET_EFAULT;
3951
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3952
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3953
    unlock_user_struct(target_ts, target_addr, 0);
3954
    return 0;
3955
}
3956

    
3957
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3958
                                               struct timespec *host_ts)
3959
{
3960
    struct target_timespec *target_ts;
3961

    
3962
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3963
        return -TARGET_EFAULT;
3964
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3965
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3966
    unlock_user_struct(target_ts, target_addr, 1);
3967
    return 0;
3968
}
3969

    
3970
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3971
static inline abi_long host_to_target_stat64(void *cpu_env,
3972
                                             abi_ulong target_addr,
3973
                                             struct stat *host_st)
3974
{
3975
#ifdef TARGET_ARM
3976
    if (((CPUARMState *)cpu_env)->eabi) {
3977
        struct target_eabi_stat64 *target_st;
3978

    
3979
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3980
            return -TARGET_EFAULT;
3981
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3982
        __put_user(host_st->st_dev, &target_st->st_dev);
3983
        __put_user(host_st->st_ino, &target_st->st_ino);
3984
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3985
        __put_user(host_st->st_ino, &target_st->__st_ino);
3986
#endif
3987
        __put_user(host_st->st_mode, &target_st->st_mode);
3988
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3989
        __put_user(host_st->st_uid, &target_st->st_uid);
3990
        __put_user(host_st->st_gid, &target_st->st_gid);
3991
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3992
        __put_user(host_st->st_size, &target_st->st_size);
3993
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3994
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3995
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3996
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3997
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3998
        unlock_user_struct(target_st, target_addr, 1);
3999
    } else
4000
#endif
4001
    {
4002
#if TARGET_LONG_BITS == 64
4003
        struct target_stat *target_st;
4004
#else
4005
        struct target_stat64 *target_st;
4006
#endif
4007

    
4008
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4009
            return -TARGET_EFAULT;
4010
        memset(target_st, 0, sizeof(*target_st));
4011
        __put_user(host_st->st_dev, &target_st->st_dev);
4012
        __put_user(host_st->st_ino, &target_st->st_ino);
4013
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4014
        __put_user(host_st->st_ino, &target_st->__st_ino);
4015
#endif
4016
        __put_user(host_st->st_mode, &target_st->st_mode);
4017
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4018
        __put_user(host_st->st_uid, &target_st->st_uid);
4019
        __put_user(host_st->st_gid, &target_st->st_gid);
4020
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4021
        /* XXX: better use of kernel struct */
4022
        __put_user(host_st->st_size, &target_st->st_size);
4023
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4024
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4025
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4026
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4027
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4028
        unlock_user_struct(target_st, target_addr, 1);
4029
    }
4030

    
4031
    return 0;
4032
}
4033
#endif
4034

    
4035
#if defined(CONFIG_USE_NPTL)
4036
/* ??? Using host futex calls even when target atomic operations
4037
   are not really atomic probably breaks things.  However implementing
4038
   futexes locally would make futexes shared between multiple processes
4039
   tricky.  However they're probably useless because guest atomic
4040
   operations won't work either.  */
4041
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4042
                    target_ulong uaddr2, int val3)
4043
{
4044
    struct timespec ts, *pts;
4045
    int base_op;
4046

    
4047
    /* ??? We assume FUTEX_* constants are the same on both host
4048
       and target.  */
4049
#ifdef FUTEX_CMD_MASK
4050
    base_op = op & FUTEX_CMD_MASK;
4051
#else
4052
    base_op = op;
4053
#endif
4054
    switch (base_op) {
4055
    case FUTEX_WAIT:
4056
        if (timeout) {
4057
            pts = &ts;
4058
            target_to_host_timespec(pts, timeout);
4059
        } else {
4060
            pts = NULL;
4061
        }
4062
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4063
                         pts, NULL, 0));
4064
    case FUTEX_WAKE:
4065
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4066
    case FUTEX_FD:
4067
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4068
    case FUTEX_REQUEUE:
4069
    case FUTEX_CMP_REQUEUE:
4070
    case FUTEX_WAKE_OP:
4071
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4072
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4073
           But the prototype takes a `struct timespec *'; insert casts
4074
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4075
           since it's not compared to guest memory.  */
4076
        pts = (struct timespec *)(uintptr_t) timeout;
4077
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4078
                                   g2h(uaddr2),
4079
                                   (base_op == FUTEX_CMP_REQUEUE
4080
                                    ? tswap32(val3)
4081
                                    : val3)));
4082
    default:
4083
        return -TARGET_ENOSYS;
4084
    }
4085
}
4086
#endif
4087

    
4088
/* Map host to target signal numbers for the wait family of syscalls.
4089
   Assume all other status bits are the same.  */
4090
static int host_to_target_waitstatus(int status)
4091
{
4092
    if (WIFSIGNALED(status)) {
4093
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4094
    }
4095
    if (WIFSTOPPED(status)) {
4096
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4097
               | (status & 0xff);
4098
    }
4099
    return status;
4100
}
4101

    
4102
int get_osversion(void)
4103
{
4104
    static int osversion;
4105
    struct new_utsname buf;
4106
    const char *s;
4107
    int i, n, tmp;
4108
    if (osversion)
4109
        return osversion;
4110
    if (qemu_uname_release && *qemu_uname_release) {
4111
        s = qemu_uname_release;
4112
    } else {
4113
        if (sys_uname(&buf))
4114
            return 0;
4115
        s = buf.release;
4116
    }
4117
    tmp = 0;
4118
    for (i = 0; i < 3; i++) {
4119
        n = 0;
4120
        while (*s >= '0' && *s <= '9') {
4121
            n *= 10;
4122
            n += *s - '0';
4123
            s++;
4124
        }
4125
        tmp = (tmp << 8) + n;
4126
        if (*s == '.')
4127
            s++;
4128
    }
4129
    osversion = tmp;
4130
    return osversion;
4131
}
4132

    
4133
/* do_syscall() should always have a single exit point at the end so
4134
   that actions, such as logging of syscall results, can be performed.
4135
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4136
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4137
                    abi_long arg2, abi_long arg3, abi_long arg4,
4138
                    abi_long arg5, abi_long arg6)
4139
{
4140
    abi_long ret;
4141
    struct stat st;
4142
    struct statfs stfs;
4143
    void *p;
4144

    
4145
#ifdef DEBUG
4146
    gemu_log("syscall %d", num);
4147
#endif
4148
    if(do_strace)
4149
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4150

    
4151
    switch(num) {
4152
    case TARGET_NR_exit:
4153
#ifdef CONFIG_USE_NPTL
4154
      /* In old applications this may be used to implement _exit(2).
4155
         However in threaded applictions it is used for thread termination,
4156
         and _exit_group is used for application termination.
4157
         Do thread termination if we have more then one thread.  */
4158
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4159
         be disabling signals.  */
4160
      if (first_cpu->next_cpu) {
4161
          TaskState *ts;
4162
          CPUState **lastp;
4163
          CPUState *p;
4164

    
4165
          cpu_list_lock();
4166
          lastp = &first_cpu;
4167
          p = first_cpu;
4168
          while (p && p != (CPUState *)cpu_env) {
4169
              lastp = &p->next_cpu;
4170
              p = p->next_cpu;
4171
          }
4172
          /* If we didn't find the CPU for this thread then something is
4173
             horribly wrong.  */
4174
          if (!p)
4175
              abort();
4176
          /* Remove the CPU from the list.  */
4177
          *lastp = p->next_cpu;
4178
          cpu_list_unlock();
4179
          ts = ((CPUState *)cpu_env)->opaque;
4180
          if (ts->child_tidptr) {
4181
              put_user_u32(0, ts->child_tidptr);
4182
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4183
                        NULL, NULL, 0);
4184
          }
4185
          /* TODO: Free CPU state.  */
4186
          pthread_exit(NULL);
4187
      }
4188
#endif
4189
#ifdef TARGET_GPROF
4190
        _mcleanup();
4191
#endif
4192
        gdb_exit(cpu_env, arg1);
4193
        _exit(arg1);
4194
        ret = 0; /* avoid warning */
4195
        break;
4196
    case TARGET_NR_read:
4197
        if (arg3 == 0)
4198
            ret = 0;
4199
        else {
4200
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4201
                goto efault;
4202
            ret = get_errno(read(arg1, p, arg3));
4203
            unlock_user(p, arg2, ret);
4204
        }
4205
        break;
4206
    case TARGET_NR_write:
4207
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4208
            goto efault;
4209
        ret = get_errno(write(arg1, p, arg3));
4210
        unlock_user(p, arg2, 0);
4211
        break;
4212
    case TARGET_NR_open:
4213
        if (!(p = lock_user_string(arg1)))
4214
            goto efault;
4215
        ret = get_errno(open(path(p),
4216
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4217
                             arg3));
4218
        unlock_user(p, arg1, 0);
4219
        break;
4220
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4221
    case TARGET_NR_openat:
4222
        if (!(p = lock_user_string(arg2)))
4223
            goto efault;
4224
        ret = get_errno(sys_openat(arg1,
4225
                                   path(p),
4226
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4227
                                   arg4));
4228
        unlock_user(p, arg2, 0);
4229
        break;
4230
#endif
4231
    case TARGET_NR_close:
4232
        ret = get_errno(close(arg1));
4233
        break;
4234
    case TARGET_NR_brk:
4235
        ret = do_brk(arg1);
4236
        break;
4237
    case TARGET_NR_fork:
4238
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4239
        break;
4240
#ifdef TARGET_NR_waitpid
4241
    case TARGET_NR_waitpid:
4242
        {
4243
            int status;
4244
            ret = get_errno(waitpid(arg1, &status, arg3));
4245
            if (!is_error(ret) && arg2
4246
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4247
                goto efault;
4248
        }
4249
        break;
4250
#endif
4251
#ifdef TARGET_NR_waitid
4252
    case TARGET_NR_waitid:
4253
        {
4254
            siginfo_t info;
4255
            info.si_pid = 0;
4256
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4257
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4258
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4259
                    goto efault;
4260
                host_to_target_siginfo(p, &info);
4261
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4262
            }
4263
        }
4264
        break;
4265
#endif
4266
#ifdef TARGET_NR_creat /* not on alpha */
4267
    case TARGET_NR_creat:
4268
        if (!(p = lock_user_string(arg1)))
4269
            goto efault;
4270
        ret = get_errno(creat(p, arg2));
4271
        unlock_user(p, arg1, 0);
4272
        break;
4273
#endif
4274
    case TARGET_NR_link:
4275
        {
4276
            void * p2;
4277
            p = lock_user_string(arg1);
4278
            p2 = lock_user_string(arg2);
4279
            if (!p || !p2)
4280
                ret = -TARGET_EFAULT;
4281
            else
4282
                ret = get_errno(link(p, p2));
4283
            unlock_user(p2, arg2, 0);
4284
            unlock_user(p, arg1, 0);
4285
        }
4286
        break;
4287
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4288
    case TARGET_NR_linkat:
4289
        {
4290
            void * p2 = NULL;
4291
            if (!arg2 || !arg4)
4292
                goto efault;
4293
            p  = lock_user_string(arg2);
4294
            p2 = lock_user_string(arg4);
4295
            if (!p || !p2)
4296
                ret = -TARGET_EFAULT;
4297
            else
4298
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4299
            unlock_user(p, arg2, 0);
4300
            unlock_user(p2, arg4, 0);
4301
        }
4302
        break;
4303
#endif
4304
    case TARGET_NR_unlink:
4305
        if (!(p = lock_user_string(arg1)))
4306
            goto efault;
4307
        ret = get_errno(unlink(p));
4308
        unlock_user(p, arg1, 0);
4309
        break;
4310
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4311
    case TARGET_NR_unlinkat:
4312
        if (!(p = lock_user_string(arg2)))
4313
            goto efault;
4314
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4315
        unlock_user(p, arg2, 0);
4316
        break;
4317
#endif
4318
    case TARGET_NR_execve:
4319
        {
4320
            char **argp, **envp;
4321
            int argc, envc;
4322
            abi_ulong gp;
4323
            abi_ulong guest_argp;
4324
            abi_ulong guest_envp;
4325
            abi_ulong addr;
4326
            char **q;
4327

    
4328
            argc = 0;
4329
            guest_argp = arg2;
4330
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4331
                if (get_user_ual(addr, gp))
4332
                    goto efault;
4333
                if (!addr)
4334
                    break;
4335
                argc++;
4336
            }
4337
            envc = 0;
4338
            guest_envp = arg3;
4339
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4340
                if (get_user_ual(addr, gp))
4341
                    goto efault;
4342
                if (!addr)
4343
                    break;
4344
                envc++;
4345
            }
4346

    
4347
            argp = alloca((argc + 1) * sizeof(void *));
4348
            envp = alloca((envc + 1) * sizeof(void *));
4349

    
4350
            for (gp = guest_argp, q = argp; gp;
4351
                  gp += sizeof(abi_ulong), q++) {
4352
                if (get_user_ual(addr, gp))
4353
                    goto execve_efault;
4354
                if (!addr)
4355
                    break;
4356
                if (!(*q = lock_user_string(addr)))
4357
                    goto execve_efault;
4358
            }
4359
            *q = NULL;
4360

    
4361
            for (gp = guest_envp, q = envp; gp;
4362
                  gp += sizeof(abi_ulong), q++) {
4363
                if (get_user_ual(addr, gp))
4364
                    goto execve_efault;
4365
                if (!addr)
4366
                    break;
4367
                if (!(*q = lock_user_string(addr)))
4368
                    goto execve_efault;
4369
            }
4370
            *q = NULL;
4371

    
4372
            if (!(p = lock_user_string(arg1)))
4373
                goto execve_efault;
4374
            ret = get_errno(execve(p, argp, envp));
4375
            unlock_user(p, arg1, 0);
4376

    
4377
            goto execve_end;
4378

    
4379
        execve_efault:
4380
            ret = -TARGET_EFAULT;
4381

    
4382
        execve_end:
4383
            for (gp = guest_argp, q = argp; *q;
4384
                  gp += sizeof(abi_ulong), q++) {
4385
                if (get_user_ual(addr, gp)
4386
                    || !addr)
4387
                    break;
4388
                unlock_user(*q, addr, 0);
4389
            }
4390
            for (gp = guest_envp, q = envp; *q;
4391
                  gp += sizeof(abi_ulong), q++) {
4392
                if (get_user_ual(addr, gp)
4393
                    || !addr)
4394
                    break;
4395
                unlock_user(*q, addr, 0);
4396
            }
4397
        }
4398
        break;
4399
    case TARGET_NR_chdir:
4400
        if (!(p = lock_user_string(arg1)))
4401
            goto efault;
4402
        ret = get_errno(chdir(p));
4403
        unlock_user(p, arg1, 0);
4404
        break;
4405
#ifdef TARGET_NR_time
4406
    case TARGET_NR_time:
4407
        {
4408
            time_t host_time;
4409
            ret = get_errno(time(&host_time));
4410
            if (!is_error(ret)
4411
                && arg1
4412
                && put_user_sal(host_time, arg1))
4413
                goto efault;
4414
        }
4415
        break;
4416
#endif
4417
    case TARGET_NR_mknod:
4418
        if (!(p = lock_user_string(arg1)))
4419
            goto efault;
4420
        ret = get_errno(mknod(p, arg2, arg3));
4421
        unlock_user(p, arg1, 0);
4422
        break;
4423
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4424
    case TARGET_NR_mknodat:
4425
        if (!(p = lock_user_string(arg2)))
4426
            goto efault;
4427
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4428
        unlock_user(p, arg2, 0);
4429
        break;
4430
#endif
4431
    case TARGET_NR_chmod:
4432
        if (!(p = lock_user_string(arg1)))
4433
            goto efault;
4434
        ret = get_errno(chmod(p, arg2));
4435
        unlock_user(p, arg1, 0);
4436
        break;
4437
#ifdef TARGET_NR_break
4438
    case TARGET_NR_break:
4439
        goto unimplemented;
4440
#endif
4441
#ifdef TARGET_NR_oldstat
4442
    case TARGET_NR_oldstat:
4443
        goto unimplemented;
4444
#endif
4445
    case TARGET_NR_lseek:
4446
        ret = get_errno(lseek(arg1, arg2, arg3));
4447
        break;
4448
#ifdef TARGET_NR_getxpid
4449
    case TARGET_NR_getxpid:
4450
#else
4451
    case TARGET_NR_getpid:
4452
#endif
4453
        ret = get_errno(getpid());
4454
        break;
4455
    case TARGET_NR_mount:
4456
                {
4457
                        /* need to look at the data field */
4458
                        void *p2, *p3;
4459
                        p = lock_user_string(arg1);
4460
                        p2 = lock_user_string(arg2);
4461
                        p3 = lock_user_string(arg3);
4462
                        if (!p || !p2 || !p3)
4463
                            ret = -TARGET_EFAULT;
4464
                        else
4465
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4466
                             * do that since it's not guaranteed to be a NULL-terminated
4467
                             * string.
4468
                             */
4469
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4470
                        unlock_user(p, arg1, 0);
4471
                        unlock_user(p2, arg2, 0);
4472
                        unlock_user(p3, arg3, 0);
4473
                        break;
4474
                }
4475
#ifdef TARGET_NR_umount
4476
    case TARGET_NR_umount:
4477
        if (!(p = lock_user_string(arg1)))
4478
            goto efault;
4479
        ret = get_errno(umount(p));
4480
        unlock_user(p, arg1, 0);
4481
        break;
4482
#endif
4483
#ifdef TARGET_NR_stime /* not on alpha */
4484
    case TARGET_NR_stime:
4485
        {
4486
            time_t host_time;
4487
            if (get_user_sal(host_time, arg1))
4488
                goto efault;
4489
            ret = get_errno(stime(&host_time));
4490
        }
4491
        break;
4492
#endif
4493
    case TARGET_NR_ptrace:
4494
        goto unimplemented;
4495
#ifdef TARGET_NR_alarm /* not on alpha */
4496
    case TARGET_NR_alarm:
4497
        ret = alarm(arg1);
4498
        break;
4499
#endif
4500
#ifdef TARGET_NR_oldfstat
4501
    case TARGET_NR_oldfstat:
4502
        goto unimplemented;
4503
#endif
4504
#ifdef TARGET_NR_pause /* not on alpha */
4505
    case TARGET_NR_pause:
4506
        ret = get_errno(pause());
4507
        break;
4508
#endif
4509
#ifdef TARGET_NR_utime
4510
    case TARGET_NR_utime:
4511
        {
4512
            struct utimbuf tbuf, *host_tbuf;
4513
            struct target_utimbuf *target_tbuf;
4514
            if (arg2) {
4515
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4516
                    goto efault;
4517
                tbuf.actime = tswapl(target_tbuf->actime);
4518
                tbuf.modtime = tswapl(target_tbuf->modtime);
4519
                unlock_user_struct(target_tbuf, arg2, 0);
4520
                host_tbuf = &tbuf;
4521
            } else {
4522
                host_tbuf = NULL;
4523
            }
4524
            if (!(p = lock_user_string(arg1)))
4525
                goto efault;
4526
            ret = get_errno(utime(p, host_tbuf));
4527
            unlock_user(p, arg1, 0);
4528
        }
4529
        break;
4530
#endif
4531
    case TARGET_NR_utimes:
4532
        {
4533
            struct timeval *tvp, tv[2];
4534
            if (arg2) {
4535
                if (copy_from_user_timeval(&tv[0], arg2)
4536
                    || copy_from_user_timeval(&tv[1],
4537
                                              arg2 + sizeof(struct target_timeval)))
4538
                    goto efault;
4539
                tvp = tv;
4540
            } else {
4541
                tvp = NULL;
4542
            }
4543
            if (!(p = lock_user_string(arg1)))
4544
                goto efault;
4545
            ret = get_errno(utimes(p, tvp));
4546
            unlock_user(p, arg1, 0);
4547
        }
4548
        break;
4549
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4550
    case TARGET_NR_futimesat:
4551
        {
4552
            struct timeval *tvp, tv[2];
4553
            if (arg3) {
4554
                if (copy_from_user_timeval(&tv[0], arg3)
4555
                    || copy_from_user_timeval(&tv[1],
4556
                                              arg3 + sizeof(struct target_timeval)))
4557
                    goto efault;
4558
                tvp = tv;
4559
            } else {
4560
                tvp = NULL;
4561
            }
4562
            if (!(p = lock_user_string(arg2)))
4563
                goto efault;
4564
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4565
            unlock_user(p, arg2, 0);
4566
        }
4567
        break;
4568
#endif
4569
#ifdef TARGET_NR_stty
4570
    case TARGET_NR_stty:
4571
        goto unimplemented;
4572
#endif
4573
#ifdef TARGET_NR_gtty
4574
    case TARGET_NR_gtty:
4575
        goto unimplemented;
4576
#endif
4577
    case TARGET_NR_access:
4578
        if (!(p = lock_user_string(arg1)))
4579
            goto efault;
4580
        ret = get_errno(access(path(p), arg2));
4581
        unlock_user(p, arg1, 0);
4582
        break;
4583
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4584
    case TARGET_NR_faccessat:
4585
        if (!(p = lock_user_string(arg2)))
4586
            goto efault;
4587
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4588
        unlock_user(p, arg2, 0);
4589
        break;
4590
#endif
4591
#ifdef TARGET_NR_nice /* not on alpha */
4592
    case TARGET_NR_nice:
4593
        ret = get_errno(nice(arg1));
4594
        break;
4595
#endif
4596
#ifdef TARGET_NR_ftime
4597
    case TARGET_NR_ftime:
4598
        goto unimplemented;
4599
#endif
4600
    case TARGET_NR_sync:
4601
        sync();
4602
        ret = 0;
4603
        break;
4604
    case TARGET_NR_kill:
4605
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4606
        break;
4607
    case TARGET_NR_rename:
4608
        {
4609
            void *p2;
4610
            p = lock_user_string(arg1);
4611
            p2 = lock_user_string(arg2);
4612
            if (!p || !p2)
4613
                ret = -TARGET_EFAULT;
4614
            else
4615
                ret = get_errno(rename(p, p2));
4616
            unlock_user(p2, arg2, 0);
4617
            unlock_user(p, arg1, 0);
4618
        }
4619
        break;
4620
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4621
    case TARGET_NR_renameat:
4622
        {
4623
            void *p2;
4624
            p  = lock_user_string(arg2);
4625
            p2 = lock_user_string(arg4);
4626
            if (!p || !p2)
4627
                ret = -TARGET_EFAULT;
4628
            else
4629
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4630
            unlock_user(p2, arg4, 0);
4631
            unlock_user(p, arg2, 0);
4632
        }
4633
        break;
4634
#endif
4635
    case TARGET_NR_mkdir:
4636
        if (!(p = lock_user_string(arg1)))
4637
            goto efault;
4638
        ret = get_errno(mkdir(p, arg2));
4639
        unlock_user(p, arg1, 0);
4640
        break;
4641
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4642
    case TARGET_NR_mkdirat:
4643
        if (!(p = lock_user_string(arg2)))
4644
            goto efault;
4645
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4646
        unlock_user(p, arg2, 0);
4647
        break;
4648
#endif
4649
    case TARGET_NR_rmdir:
4650
        if (!(p = lock_user_string(arg1)))
4651
            goto efault;
4652
        ret = get_errno(rmdir(p));
4653
        unlock_user(p, arg1, 0);
4654
        break;
4655
    case TARGET_NR_dup:
4656
        ret = get_errno(dup(arg1));
4657
        break;
4658
    case TARGET_NR_pipe:
4659
        ret = do_pipe(cpu_env, arg1, 0);
4660
        break;
4661
#ifdef TARGET_NR_pipe2
4662
    case TARGET_NR_pipe2:
4663
        ret = do_pipe(cpu_env, arg1, arg2);
4664
        break;
4665
#endif
4666
    case TARGET_NR_times:
4667
        {
4668
            struct target_tms *tmsp;
4669
            struct tms tms;
4670
            ret = get_errno(times(&tms));
4671
            if (arg1) {
4672
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4673
                if (!tmsp)
4674
                    goto efault;
4675
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4676
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4677
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4678
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4679
            }
4680
            if (!is_error(ret))
4681
                ret = host_to_target_clock_t(ret);
4682
        }
4683
        break;
4684
#ifdef TARGET_NR_prof
4685
    case TARGET_NR_prof:
4686
        goto unimplemented;
4687
#endif
4688
#ifdef TARGET_NR_signal
4689
    case TARGET_NR_signal:
4690
        goto unimplemented;
4691
#endif
4692
    case TARGET_NR_acct:
4693
        if (arg1 == 0) {
4694
            ret = get_errno(acct(NULL));
4695
        } else {
4696
            if (!(p = lock_user_string(arg1)))
4697
                goto efault;
4698
            ret = get_errno(acct(path(p)));
4699
            unlock_user(p, arg1, 0);
4700
        }
4701
        break;
4702
#ifdef TARGET_NR_umount2 /* not on alpha */
4703
    case TARGET_NR_umount2:
4704
        if (!(p = lock_user_string(arg1)))
4705
            goto efault;
4706
        ret = get_errno(umount2(p, arg2));
4707
        unlock_user(p, arg1, 0);
4708
        break;
4709
#endif
4710
#ifdef TARGET_NR_lock
4711
    case TARGET_NR_lock:
4712
        goto unimplemented;
4713
#endif
4714
    case TARGET_NR_ioctl:
4715
        ret = do_ioctl(arg1, arg2, arg3);
4716
        break;
4717
    case TARGET_NR_fcntl:
4718
        ret = do_fcntl(arg1, arg2, arg3);
4719
        break;
4720
#ifdef TARGET_NR_mpx
4721
    case TARGET_NR_mpx:
4722
        goto unimplemented;
4723
#endif
4724
    case TARGET_NR_setpgid:
4725
        ret = get_errno(setpgid(arg1, arg2));
4726
        break;
4727
#ifdef TARGET_NR_ulimit
4728
    case TARGET_NR_ulimit:
4729
        goto unimplemented;
4730
#endif
4731
#ifdef TARGET_NR_oldolduname
4732
    case TARGET_NR_oldolduname:
4733
        goto unimplemented;
4734
#endif
4735
    case TARGET_NR_umask:
4736
        ret = get_errno(umask(arg1));
4737
        break;
4738
    case TARGET_NR_chroot:
4739
        if (!(p = lock_user_string(arg1)))
4740
            goto efault;
4741
        ret = get_errno(chroot(p));
4742
        unlock_user(p, arg1, 0);
4743
        break;
4744
    case TARGET_NR_ustat:
4745
        goto unimplemented;
4746
    case TARGET_NR_dup2:
4747
        ret = get_errno(dup2(arg1, arg2));
4748
        break;
4749
#ifdef TARGET_NR_getppid /* not on alpha */
4750
    case TARGET_NR_getppid:
4751
        ret = get_errno(getppid());
4752
        break;
4753
#endif
4754
    case TARGET_NR_getpgrp:
4755
        ret = get_errno(getpgrp());
4756
        break;
4757
    case TARGET_NR_setsid:
4758
        ret = get_errno(setsid());
4759
        break;
4760
#ifdef TARGET_NR_sigaction
4761
    case TARGET_NR_sigaction:
4762
        {
4763
#if !defined(TARGET_MIPS)
4764
            struct target_old_sigaction *old_act;
4765
            struct target_sigaction act, oact, *pact;
4766
            if (arg2) {
4767
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4768
                    goto efault;
4769
                act._sa_handler = old_act->_sa_handler;
4770
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4771
                act.sa_flags = old_act->sa_flags;
4772
                act.sa_restorer = old_act->sa_restorer;
4773
                unlock_user_struct(old_act, arg2, 0);
4774
                pact = &act;
4775
            } else {
4776
                pact = NULL;
4777
            }
4778
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4779
            if (!is_error(ret) && arg3) {
4780
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4781
                    goto efault;
4782
                old_act->_sa_handler = oact._sa_handler;
4783
                old_act->sa_mask = oact.sa_mask.sig[0];
4784
                old_act->sa_flags = oact.sa_flags;
4785
                old_act->sa_restorer = oact.sa_restorer;
4786
                unlock_user_struct(old_act, arg3, 1);
4787
            }
4788
#else
4789
            struct target_sigaction act, oact, *pact, *old_act;
4790

    
4791
            if (arg2) {
4792
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4793
                    goto efault;
4794
                act._sa_handler = old_act->_sa_handler;
4795
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4796
                act.sa_flags = old_act->sa_flags;
4797
                unlock_user_struct(old_act, arg2, 0);
4798
                pact = &act;
4799
            } else {
4800
                pact = NULL;
4801
            }
4802

    
4803
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4804

    
4805
            if (!is_error(ret) && arg3) {
4806
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4807
                    goto efault;
4808
                old_act->_sa_handler = oact._sa_handler;
4809
                old_act->sa_flags = oact.sa_flags;
4810
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4811
                old_act->sa_mask.sig[1] = 0;
4812
                old_act->sa_mask.sig[2] = 0;
4813
                old_act->sa_mask.sig[3] = 0;
4814
                unlock_user_struct(old_act, arg3, 1);
4815
            }
4816
#endif
4817
        }
4818
        break;
4819
#endif
4820
    case TARGET_NR_rt_sigaction:
4821
        {
4822
            struct target_sigaction *act;
4823
            struct target_sigaction *oact;
4824

    
4825
            if (arg2) {
4826
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4827
                    goto efault;
4828
            } else
4829
                act = NULL;
4830
            if (arg3) {
4831
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4832
                    ret = -TARGET_EFAULT;
4833
                    goto rt_sigaction_fail;
4834
                }
4835
            } else
4836
                oact = NULL;
4837
            ret = get_errno(do_sigaction(arg1, act, oact));
4838
        rt_sigaction_fail:
4839
            if (act)
4840
                unlock_user_struct(act, arg2, 0);
4841
            if (oact)
4842
                unlock_user_struct(oact, arg3, 1);
4843
        }
4844
        break;
4845
#ifdef TARGET_NR_sgetmask /* not on alpha */
4846
    case TARGET_NR_sgetmask:
4847
        {
4848
            sigset_t cur_set;
4849
            abi_ulong target_set;
4850
            sigprocmask(0, NULL, &cur_set);
4851
            host_to_target_old_sigset(&target_set, &cur_set);
4852
            ret = target_set;
4853
        }
4854
        break;
4855
#endif
4856
#ifdef TARGET_NR_ssetmask /* not on alpha */
4857
    case TARGET_NR_ssetmask:
4858
        {
4859
            sigset_t set, oset, cur_set;
4860
            abi_ulong target_set = arg1;
4861
            sigprocmask(0, NULL, &cur_set);
4862
            target_to_host_old_sigset(&set, &target_set);
4863
            sigorset(&set, &set, &cur_set);
4864
            sigprocmask(SIG_SETMASK, &set, &oset);
4865
            host_to_target_old_sigset(&target_set, &oset);
4866
            ret = target_set;
4867
        }
4868
        break;
4869
#endif
4870
#ifdef TARGET_NR_sigprocmask
4871
    case TARGET_NR_sigprocmask:
4872
        {
4873
            int how = arg1;
4874
            sigset_t set, oldset, *set_ptr;
4875

    
4876
            if (arg2) {
4877
                switch(how) {
4878
                case TARGET_SIG_BLOCK:
4879
                    how = SIG_BLOCK;
4880
                    break;
4881
                case TARGET_SIG_UNBLOCK:
4882
                    how = SIG_UNBLOCK;
4883
                    break;
4884
                case TARGET_SIG_SETMASK:
4885
                    how = SIG_SETMASK;
4886
                    break;
4887
                default:
4888
                    ret = -TARGET_EINVAL;
4889
                    goto fail;
4890
                }
4891
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4892
                    goto efault;
4893
                target_to_host_old_sigset(&set, p);
4894
                unlock_user(p, arg2, 0);
4895
                set_ptr = &set;
4896
            } else {
4897
                how = 0;
4898
                set_ptr = NULL;
4899
            }
4900
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4901
            if (!is_error(ret) && arg3) {
4902
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4903
                    goto efault;
4904
                host_to_target_old_sigset(p, &oldset);
4905
                unlock_user(p, arg3, sizeof(target_sigset_t));
4906
            }
4907
        }
4908
        break;
4909
#endif
4910
    case TARGET_NR_rt_sigprocmask:
4911
        {
4912
            int how = arg1;
4913
            sigset_t set, oldset, *set_ptr;
4914

    
4915
            if (arg2) {
4916
                switch(how) {
4917
                case TARGET_SIG_BLOCK:
4918
                    how = SIG_BLOCK;
4919
                    break;
4920
                case TARGET_SIG_UNBLOCK:
4921
                    how = SIG_UNBLOCK;
4922
                    break;
4923
                case TARGET_SIG_SETMASK:
4924
                    how = SIG_SETMASK;
4925
                    break;
4926
                default:
4927
                    ret = -TARGET_EINVAL;
4928
                    goto fail;
4929
                }
4930
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4931
                    goto efault;
4932
                target_to_host_sigset(&set, p);
4933
                unlock_user(p, arg2, 0);
4934
                set_ptr = &set;
4935
            } else {
4936
                how = 0;
4937
                set_ptr = NULL;
4938
            }
4939
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4940
            if (!is_error(ret) && arg3) {
4941
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4942
                    goto efault;
4943
                host_to_target_sigset(p, &oldset);
4944
                unlock_user(p, arg3, sizeof(target_sigset_t));
4945
            }
4946
        }
4947
        break;
4948
#ifdef TARGET_NR_sigpending
4949
    case TARGET_NR_sigpending:
4950
        {
4951
            sigset_t set;
4952
            ret = get_errno(sigpending(&set));
4953
            if (!is_error(ret)) {
4954
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4955
                    goto efault;
4956
                host_to_target_old_sigset(p, &set);
4957
                unlock_user(p, arg1, sizeof(target_sigset_t));
4958
            }
4959
        }
4960
        break;
4961
#endif
4962
    case TARGET_NR_rt_sigpending:
4963
        {
4964
            sigset_t set;
4965
            ret = get_errno(sigpending(&set));
4966
            if (!is_error(ret)) {
4967
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4968
                    goto efault;
4969
                host_to_target_sigset(p, &set);
4970
                unlock_user(p, arg1, sizeof(target_sigset_t));
4971
            }
4972
        }
4973
        break;
4974
#ifdef TARGET_NR_sigsuspend
4975
    case TARGET_NR_sigsuspend:
4976
        {
4977
            sigset_t set;
4978
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4979
                goto efault;
4980
            target_to_host_old_sigset(&set, p);
4981
            unlock_user(p, arg1, 0);
4982
            ret = get_errno(sigsuspend(&set));
4983
        }
4984
        break;
4985
#endif
4986
    case TARGET_NR_rt_sigsuspend:
4987
        {
4988
            sigset_t set;
4989
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4990
                goto efault;
4991
            target_to_host_sigset(&set, p);
4992
            unlock_user(p, arg1, 0);
4993
            ret = get_errno(sigsuspend(&set));
4994
        }
4995
        break;
4996
    case TARGET_NR_rt_sigtimedwait:
4997
        {
4998
            sigset_t set;
4999
            struct timespec uts, *puts;
5000
            siginfo_t uinfo;
5001

    
5002
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5003
                goto efault;
5004
            target_to_host_sigset(&set, p);
5005
            unlock_user(p, arg1, 0);
5006
            if (arg3) {
5007
                puts = &uts;
5008
                target_to_host_timespec(puts, arg3);
5009
            } else {
5010
                puts = NULL;
5011
            }
5012
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5013
            if (!is_error(ret) && arg2) {
5014
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5015
                    goto efault;
5016
                host_to_target_siginfo(p, &uinfo);
5017
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5018
            }
5019
        }
5020
        break;
5021
    case TARGET_NR_rt_sigqueueinfo:
5022
        {
5023
            siginfo_t uinfo;
5024
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5025
                goto efault;
5026
            target_to_host_siginfo(&uinfo, p);
5027
            unlock_user(p, arg1, 0);
5028
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5029
        }
5030
        break;
5031
#ifdef TARGET_NR_sigreturn
5032
    case TARGET_NR_sigreturn:
5033
        /* NOTE: ret is eax, so not transcoding must be done */
5034
        ret = do_sigreturn(cpu_env);
5035
        break;
5036
#endif
5037
    case TARGET_NR_rt_sigreturn:
5038
        /* NOTE: ret is eax, so not transcoding must be done */
5039
        ret = do_rt_sigreturn(cpu_env);
5040
        break;
5041
    case TARGET_NR_sethostname:
5042
        if (!(p = lock_user_string(arg1)))
5043
            goto efault;
5044
        ret = get_errno(sethostname(p, arg2));
5045
        unlock_user(p, arg1, 0);
5046
        break;
5047
    case TARGET_NR_setrlimit:
5048
        {
5049
            /* XXX: convert resource ? */
5050
            int resource = arg1;
5051
            struct target_rlimit *target_rlim;
5052
            struct rlimit rlim;
5053
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5054
                goto efault;
5055
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5056
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
5057
            unlock_user_struct(target_rlim, arg2, 0);
5058
            ret = get_errno(setrlimit(resource, &rlim));
5059
        }
5060
        break;
5061
    case TARGET_NR_getrlimit:
5062
        {
5063
            /* XXX: convert resource ? */
5064
            int resource = arg1;
5065
            struct target_rlimit *target_rlim;
5066
            struct rlimit rlim;
5067

    
5068
            ret = get_errno(getrlimit(resource, &rlim));
5069
            if (!is_error(ret)) {
5070
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5071
                    goto efault;
5072
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5073
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
5074
                unlock_user_struct(target_rlim, arg2, 1);
5075
            }
5076
        }
5077
        break;
5078
    case TARGET_NR_getrusage:
5079
        {
5080
            struct rusage rusage;
5081
            ret = get_errno(getrusage(arg1, &rusage));
5082
            if (!is_error(ret)) {
5083
                host_to_target_rusage(arg2, &rusage);
5084
            }
5085
        }
5086
        break;
5087
    case TARGET_NR_gettimeofday:
5088
        {
5089
            struct timeval tv;
5090
            ret = get_errno(gettimeofday(&tv, NULL));
5091
            if (!is_error(ret)) {
5092
                if (copy_to_user_timeval(arg1, &tv))
5093
                    goto efault;
5094
            }
5095
        }
5096
        break;
5097
    case TARGET_NR_settimeofday:
5098
        {
5099
            struct timeval tv;
5100
            if (copy_from_user_timeval(&tv, arg1))
5101
                goto efault;
5102
            ret = get_errno(settimeofday(&tv, NULL));
5103
        }
5104
        break;
5105
#ifdef TARGET_NR_select
5106
    case TARGET_NR_select:
5107
        {
5108
            struct target_sel_arg_struct *sel;
5109
            abi_ulong inp, outp, exp, tvp;
5110
            long nsel;
5111

    
5112
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5113
                goto efault;
5114
            nsel = tswapl(sel->n);
5115
            inp = tswapl(sel->inp);
5116
            outp = tswapl(sel->outp);
5117
            exp = tswapl(sel->exp);
5118
            tvp = tswapl(sel->tvp);
5119
            unlock_user_struct(sel, arg1, 0);
5120
            ret = do_select(nsel, inp, outp, exp, tvp);
5121
        }
5122
        break;
5123
#endif
5124
    case TARGET_NR_symlink:
5125
        {
5126
            void *p2;
5127
            p = lock_user_string(arg1);
5128
            p2 = lock_user_string(arg2);
5129
            if (!p || !p2)
5130
                ret = -TARGET_EFAULT;
5131
            else
5132
                ret = get_errno(symlink(p, p2));
5133
            unlock_user(p2, arg2, 0);
5134
            unlock_user(p, arg1, 0);
5135
        }
5136
        break;
5137
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5138
    case TARGET_NR_symlinkat:
5139
        {
5140
            void *p2;
5141
            p  = lock_user_string(arg1);
5142
            p2 = lock_user_string(arg3);
5143
            if (!p || !p2)
5144
                ret = -TARGET_EFAULT;
5145
            else
5146
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5147
            unlock_user(p2, arg3, 0);
5148
            unlock_user(p, arg1, 0);
5149
        }
5150
        break;
5151
#endif
5152
#ifdef TARGET_NR_oldlstat
5153
    case TARGET_NR_oldlstat:
5154
        goto unimplemented;
5155
#endif
5156
    case TARGET_NR_readlink:
5157
        {
5158
            void *p2, *temp;
5159
            p = lock_user_string(arg1);
5160
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5161
            if (!p || !p2)
5162
                ret = -TARGET_EFAULT;
5163
            else {
5164
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5165
                    char real[PATH_MAX];
5166
                    temp = realpath(exec_path,real);
5167
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5168
                    snprintf((char *)p2, arg3, "%s", real);
5169
                    }
5170
                else
5171
                    ret = get_errno(readlink(path(p), p2, arg3));
5172
            }
5173
            unlock_user(p2, arg2, ret);
5174
            unlock_user(p, arg1, 0);
5175
        }
5176
        break;
5177
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5178
    case TARGET_NR_readlinkat:
5179
        {
5180
            void *p2;
5181
            p  = lock_user_string(arg2);
5182
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5183
            if (!p || !p2)
5184
                ret = -TARGET_EFAULT;
5185
            else
5186
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5187
            unlock_user(p2, arg3, ret);
5188
            unlock_user(p, arg2, 0);
5189
        }
5190
        break;
5191
#endif
5192
#ifdef TARGET_NR_uselib
5193
    case TARGET_NR_uselib:
5194
        goto unimplemented;
5195
#endif
5196
#ifdef TARGET_NR_swapon
5197
    case TARGET_NR_swapon:
5198
        if (!(p = lock_user_string(arg1)))
5199
            goto efault;
5200
        ret = get_errno(swapon(p, arg2));
5201
        unlock_user(p, arg1, 0);
5202
        break;
5203
#endif
5204
    case TARGET_NR_reboot:
5205
        goto unimplemented;
5206
#ifdef TARGET_NR_readdir
5207
    case TARGET_NR_readdir:
5208
        goto unimplemented;
5209
#endif
5210
#ifdef TARGET_NR_mmap
5211
    case TARGET_NR_mmap:
5212
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5213
        {
5214
            abi_ulong *v;
5215
            abi_ulong v1, v2, v3, v4, v5, v6;
5216
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5217
                goto efault;
5218
            v1 = tswapl(v[0]);
5219
            v2 = tswapl(v[1]);
5220
            v3 = tswapl(v[2]);
5221
            v4 = tswapl(v[3]);
5222
            v5 = tswapl(v[4]);
5223
            v6 = tswapl(v[5]);
5224
            unlock_user(v, arg1, 0);
5225
            ret = get_errno(target_mmap(v1, v2, v3,
5226
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5227
                                        v5, v6));
5228
        }
5229
#else
5230
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5231
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5232
                                    arg5,
5233
                                    arg6));
5234
#endif
5235
        break;
5236
#endif
5237
#ifdef TARGET_NR_mmap2
5238
    case TARGET_NR_mmap2:
5239
#ifndef MMAP_SHIFT
5240
#define MMAP_SHIFT 12
5241
#endif
5242
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5243
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5244
                                    arg5,
5245
                                    arg6 << MMAP_SHIFT));
5246
        break;
5247
#endif
5248
    case TARGET_NR_munmap:
5249
        ret = get_errno(target_munmap(arg1, arg2));
5250
        break;
5251
    case TARGET_NR_mprotect:
5252
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5253
        break;
5254
#ifdef TARGET_NR_mremap
5255
    case TARGET_NR_mremap:
5256
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5257
        break;
5258
#endif
5259
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5260
#ifdef TARGET_NR_msync
5261
    case TARGET_NR_msync:
5262
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5263
        break;
5264
#endif
5265
#ifdef TARGET_NR_mlock
5266
    case TARGET_NR_mlock:
5267
        ret = get_errno(mlock(g2h(arg1), arg2));
5268
        break;
5269
#endif
5270
#ifdef TARGET_NR_munlock
5271
    case TARGET_NR_munlock:
5272
        ret = get_errno(munlock(g2h(arg1), arg2));
5273
        break;
5274
#endif
5275
#ifdef TARGET_NR_mlockall
5276
    case TARGET_NR_mlockall:
5277
        ret = get_errno(mlockall(arg1));
5278
        break;
5279
#endif
5280
#ifdef TARGET_NR_munlockall
5281
    case TARGET_NR_munlockall:
5282
        ret = get_errno(munlockall());
5283
        break;
5284
#endif
5285
    case TARGET_NR_truncate:
5286
        if (!(p = lock_user_string(arg1)))
5287
            goto efault;
5288
        ret = get_errno(truncate(p, arg2));
5289
        unlock_user(p, arg1, 0);
5290
        break;
5291
    case TARGET_NR_ftruncate:
5292
        ret = get_errno(ftruncate(arg1, arg2));
5293
        break;
5294
    case TARGET_NR_fchmod:
5295
        ret = get_errno(fchmod(arg1, arg2));
5296
        break;
5297
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5298
    case TARGET_NR_fchmodat:
5299
        if (!(p = lock_user_string(arg2)))
5300
            goto efault;
5301
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5302
        unlock_user(p, arg2, 0);
5303
        break;
5304
#endif
5305
    case TARGET_NR_getpriority:
5306
        /* libc does special remapping of the return value of
5307
         * sys_getpriority() so it's just easiest to call
5308
         * sys_getpriority() directly rather than through libc. */
5309
        ret = sys_getpriority(arg1, arg2);
5310
        break;
5311
    case TARGET_NR_setpriority:
5312
        ret = get_errno(setpriority(arg1, arg2, arg3));
5313
        break;
5314
#ifdef TARGET_NR_profil
5315
    case TARGET_NR_profil:
5316
        goto unimplemented;
5317
#endif
5318
    case TARGET_NR_statfs:
5319
        if (!(p = lock_user_string(arg1)))
5320
            goto efault;
5321
        ret = get_errno(statfs(path(p), &stfs));
5322
        unlock_user(p, arg1, 0);
5323
    convert_statfs:
5324
        if (!is_error(ret)) {
5325
            struct target_statfs *target_stfs;
5326

    
5327
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5328
                goto efault;
5329
            __put_user(stfs.f_type, &target_stfs->f_type);
5330
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5331
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5332
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5333
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5334
            __put_user(stfs.f_files, &target_stfs->f_files);
5335
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5336
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5337
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5338
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5339
            unlock_user_struct(target_stfs, arg2, 1);
5340
        }
5341
        break;
5342
    case TARGET_NR_fstatfs:
5343
        ret = get_errno(fstatfs(arg1, &stfs));
5344
        goto convert_statfs;
5345
#ifdef TARGET_NR_statfs64
5346
    case TARGET_NR_statfs64:
5347
        if (!(p = lock_user_string(arg1)))
5348
            goto efault;
5349
        ret = get_errno(statfs(path(p), &stfs));
5350
        unlock_user(p, arg1, 0);
5351
    convert_statfs64:
5352
        if (!is_error(ret)) {
5353
            struct target_statfs64 *target_stfs;
5354

    
5355
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5356
                goto efault;
5357
            __put_user(stfs.f_type, &target_stfs->f_type);
5358
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5359
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5360
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5361
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5362
            __put_user(stfs.f_files, &target_stfs->f_files);
5363
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5364
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5365
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5366
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5367
            unlock_user_struct(target_stfs, arg3, 1);
5368
        }
5369
        break;
5370
    case TARGET_NR_fstatfs64:
5371
        ret = get_errno(fstatfs(arg1, &stfs));
5372
        goto convert_statfs64;
5373
#endif
5374
#ifdef TARGET_NR_ioperm
5375
    case TARGET_NR_ioperm:
5376
        goto unimplemented;
5377
#endif
5378
#ifdef TARGET_NR_socketcall
5379
    case TARGET_NR_socketcall:
5380
        ret = do_socketcall(arg1, arg2);
5381
        break;
5382
#endif
5383
#ifdef TARGET_NR_accept
5384
    case TARGET_NR_accept:
5385
        ret = do_accept(arg1, arg2, arg3);
5386
        break;
5387
#endif
5388
#ifdef TARGET_NR_bind
5389
    case TARGET_NR_bind:
5390
        ret = do_bind(arg1, arg2, arg3);
5391
        break;
5392
#endif
5393
#ifdef TARGET_NR_connect
5394
    case TARGET_NR_connect:
5395
        ret = do_connect(arg1, arg2, arg3);
5396
        break;
5397
#endif
5398
#ifdef TARGET_NR_getpeername
5399
    case TARGET_NR_getpeername:
5400
        ret = do_getpeername(arg1, arg2, arg3);
5401
        break;
5402
#endif
5403
#ifdef TARGET_NR_getsockname
5404
    case TARGET_NR_getsockname:
5405
        ret = do_getsockname(arg1, arg2, arg3);
5406
        break;
5407
#endif
5408
#ifdef TARGET_NR_getsockopt
5409
    case TARGET_NR_getsockopt:
5410
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5411
        break;
5412
#endif
5413
#ifdef TARGET_NR_listen
5414
    case TARGET_NR_listen:
5415
        ret = get_errno(listen(arg1, arg2));
5416
        break;
5417
#endif
5418
#ifdef TARGET_NR_recv
5419
    case TARGET_NR_recv:
5420
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5421
        break;
5422
#endif
5423
#ifdef TARGET_NR_recvfrom
5424
    case TARGET_NR_recvfrom:
5425
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5426
        break;
5427
#endif
5428
#ifdef TARGET_NR_recvmsg
5429
    case TARGET_NR_recvmsg:
5430
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5431
        break;
5432
#endif
5433
#ifdef TARGET_NR_send
5434
    case TARGET_NR_send:
5435
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5436
        break;
5437
#endif
5438
#ifdef TARGET_NR_sendmsg
5439
    case TARGET_NR_sendmsg:
5440
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5441
        break;
5442
#endif
5443
#ifdef TARGET_NR_sendto
5444
    case TARGET_NR_sendto:
5445
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5446
        break;
5447
#endif
5448
#ifdef TARGET_NR_shutdown
5449
    case TARGET_NR_shutdown:
5450
        ret = get_errno(shutdown(arg1, arg2));
5451
        break;
5452
#endif
5453
#ifdef TARGET_NR_socket
5454
    case TARGET_NR_socket:
5455
        ret = do_socket(arg1, arg2, arg3);
5456
        break;
5457
#endif
5458
#ifdef TARGET_NR_socketpair
5459
    case TARGET_NR_socketpair:
5460
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5461
        break;
5462
#endif
5463
#ifdef TARGET_NR_setsockopt
5464
    case TARGET_NR_setsockopt:
5465
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5466
        break;
5467
#endif
5468

    
5469
    case TARGET_NR_syslog:
5470
        if (!(p = lock_user_string(arg2)))
5471
            goto efault;
5472
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5473
        unlock_user(p, arg2, 0);
5474
        break;
5475

    
5476
    case TARGET_NR_setitimer:
5477
        {
5478
            struct itimerval value, ovalue, *pvalue;
5479

    
5480
            if (arg2) {
5481
                pvalue = &value;
5482
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5483
                    || copy_from_user_timeval(&pvalue->it_value,
5484
                                              arg2 + sizeof(struct target_timeval)))
5485
                    goto efault;
5486
            } else {
5487
                pvalue = NULL;
5488
            }
5489
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5490
            if (!is_error(ret) && arg3) {
5491
                if (copy_to_user_timeval(arg3,
5492
                                         &ovalue.it_interval)
5493
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5494
                                            &ovalue.it_value))
5495
                    goto efault;
5496
            }
5497
        }
5498
        break;
5499
    case TARGET_NR_getitimer:
5500
        {
5501
            struct itimerval value;
5502

    
5503
            ret = get_errno(getitimer(arg1, &value));
5504
            if (!is_error(ret) && arg2) {
5505
                if (copy_to_user_timeval(arg2,
5506
                                         &value.it_interval)
5507
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5508
                                            &value.it_value))
5509
                    goto efault;
5510
            }
5511
        }
5512
        break;
5513
    case TARGET_NR_stat:
5514
        if (!(p = lock_user_string(arg1)))
5515
            goto efault;
5516
        ret = get_errno(stat(path(p), &st));
5517
        unlock_user(p, arg1, 0);
5518
        goto do_stat;
5519
    case TARGET_NR_lstat:
5520
        if (!(p = lock_user_string(arg1)))
5521
            goto efault;
5522
        ret = get_errno(lstat(path(p), &st));
5523
        unlock_user(p, arg1, 0);
5524
        goto do_stat;
5525
    case TARGET_NR_fstat:
5526
        {
5527
            ret = get_errno(fstat(arg1, &st));
5528
        do_stat:
5529
            if (!is_error(ret)) {
5530
                struct target_stat *target_st;
5531

    
5532
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5533
                    goto efault;
5534
                memset(target_st, 0, sizeof(*target_st));
5535
                __put_user(st.st_dev, &target_st->st_dev);
5536
                __put_user(st.st_ino, &target_st->st_ino);
5537
                __put_user(st.st_mode, &target_st->st_mode);
5538
                __put_user(st.st_uid, &target_st->st_uid);
5539
                __put_user(st.st_gid, &target_st->st_gid);
5540
                __put_user(st.st_nlink, &target_st->st_nlink);
5541
                __put_user(st.st_rdev, &target_st->st_rdev);
5542
                __put_user(st.st_size, &target_st->st_size);
5543
                __put_user(st.st_blksize, &target_st->st_blksize);
5544
                __put_user(st.st_blocks, &target_st->st_blocks);
5545
                __put_user(st.st_atime, &target_st->target_st_atime);
5546
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5547
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5548
                unlock_user_struct(target_st, arg2, 1);
5549
            }
5550
        }
5551
        break;
5552
#ifdef TARGET_NR_olduname
5553
    case TARGET_NR_olduname:
5554
        goto unimplemented;
5555
#endif
5556
#ifdef TARGET_NR_iopl
5557
    case TARGET_NR_iopl:
5558
        goto unimplemented;
5559
#endif
5560
    case TARGET_NR_vhangup:
5561
        ret = get_errno(vhangup());
5562
        break;
5563
#ifdef TARGET_NR_idle
5564
    case TARGET_NR_idle:
5565
        goto unimplemented;
5566
#endif
5567
#ifdef TARGET_NR_syscall
5568
    case TARGET_NR_syscall:
5569
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5570
            break;
5571
#endif
5572
    case TARGET_NR_wait4:
5573
        {
5574
            int status;
5575
            abi_long status_ptr = arg2;
5576
            struct rusage rusage, *rusage_ptr;
5577
            abi_ulong target_rusage = arg4;
5578
            if (target_rusage)
5579
                rusage_ptr = &rusage;
5580
            else
5581
                rusage_ptr = NULL;
5582
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5583
            if (!is_error(ret)) {
5584
                if (status_ptr) {
5585
                    status = host_to_target_waitstatus(status);
5586
                    if (put_user_s32(status, status_ptr))
5587
                        goto efault;
5588
                }
5589
                if (target_rusage)
5590
                    host_to_target_rusage(target_rusage, &rusage);
5591
            }
5592
        }
5593
        break;
5594
#ifdef TARGET_NR_swapoff
5595
    case TARGET_NR_swapoff:
5596
        if (!(p = lock_user_string(arg1)))
5597
            goto efault;
5598
        ret = get_errno(swapoff(p));
5599
        unlock_user(p, arg1, 0);
5600
        break;
5601
#endif
5602
    case TARGET_NR_sysinfo:
5603
        {
5604
            struct target_sysinfo *target_value;
5605
            struct sysinfo value;
5606
            ret = get_errno(sysinfo(&value));
5607
            if (!is_error(ret) && arg1)
5608
            {
5609
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5610
                    goto efault;
5611
                __put_user(value.uptime, &target_value->uptime);
5612
                __put_user(value.loads[0], &target_value->loads[0]);
5613
                __put_user(value.loads[1], &target_value->loads[1]);
5614
                __put_user(value.loads[2], &target_value->loads[2]);
5615
                __put_user(value.totalram, &target_value->totalram);
5616
                __put_user(value.freeram, &target_value->freeram);
5617
                __put_user(value.sharedram, &target_value->sharedram);
5618
                __put_user(value.bufferram, &target_value->bufferram);
5619
                __put_user(value.totalswap, &target_value->totalswap);
5620
                __put_user(value.freeswap, &target_value->freeswap);
5621
                __put_user(value.procs, &target_value->procs);
5622
                __put_user(value.totalhigh, &target_value->totalhigh);
5623
                __put_user(value.freehigh, &target_value->freehigh);
5624
                __put_user(value.mem_unit, &target_value->mem_unit);
5625
                unlock_user_struct(target_value, arg1, 1);
5626
            }
5627
        }
5628
        break;
5629
#ifdef TARGET_NR_ipc
5630
    case TARGET_NR_ipc:
5631
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5632
        break;
5633
#endif
5634
#ifdef TARGET_NR_semget
5635
    case TARGET_NR_semget:
5636
        ret = get_errno(semget(arg1, arg2, arg3));
5637
        break;
5638
#endif
5639
#ifdef TARGET_NR_semop
5640
    case TARGET_NR_semop:
5641
        ret = get_errno(do_semop(arg1, arg2, arg3));
5642
        break;
5643
#endif
5644
#ifdef TARGET_NR_semctl
5645
    case TARGET_NR_semctl:
5646
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5647
        break;
5648
#endif
5649
#ifdef TARGET_NR_msgctl
5650
    case TARGET_NR_msgctl:
5651
        ret = do_msgctl(arg1, arg2, arg3);
5652
        break;
5653
#endif
5654
#ifdef TARGET_NR_msgget
5655
    case TARGET_NR_msgget:
5656
        ret = get_errno(msgget(arg1, arg2));
5657
        break;
5658
#endif
5659
#ifdef TARGET_NR_msgrcv
5660
    case TARGET_NR_msgrcv:
5661
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5662
        break;
5663
#endif
5664
#ifdef TARGET_NR_msgsnd
5665
    case TARGET_NR_msgsnd:
5666
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5667
        break;
5668
#endif
5669
#ifdef TARGET_NR_shmget
5670
    case TARGET_NR_shmget:
5671
        ret = get_errno(shmget(arg1, arg2, arg3));
5672
        break;
5673
#endif
5674
#ifdef TARGET_NR_shmctl
5675
    case TARGET_NR_shmctl:
5676
        ret = do_shmctl(arg1, arg2, arg3);
5677
        break;
5678
#endif
5679
#ifdef TARGET_NR_shmat
5680
    case TARGET_NR_shmat:
5681
        ret = do_shmat(arg1, arg2, arg3);
5682
        break;
5683
#endif
5684
#ifdef TARGET_NR_shmdt
5685
    case TARGET_NR_shmdt:
5686
        ret = do_shmdt(arg1);
5687
        break;
5688
#endif
5689
    case TARGET_NR_fsync:
5690
        ret = get_errno(fsync(arg1));
5691
        break;
5692
    case TARGET_NR_clone:
5693
#if defined(TARGET_SH4)
5694
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5695
#elif defined(TARGET_CRIS)
5696
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5697
#else
5698
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5699
#endif
5700
        break;
5701
#ifdef __NR_exit_group
5702
        /* new thread calls */
5703
    case TARGET_NR_exit_group:
5704
#ifdef TARGET_GPROF
5705
        _mcleanup();
5706
#endif
5707
        gdb_exit(cpu_env, arg1);
5708
        ret = get_errno(exit_group(arg1));
5709
        break;
5710
#endif
5711
    case TARGET_NR_setdomainname:
5712
        if (!(p = lock_user_string(arg1)))
5713
            goto efault;
5714
        ret = get_errno(setdomainname(p, arg2));
5715
        unlock_user(p, arg1, 0);
5716
        break;
5717
    case TARGET_NR_uname:
5718
        /* no need to transcode because we use the linux syscall */
5719
        {
5720
            struct new_utsname * buf;
5721

    
5722
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5723
                goto efault;
5724
            ret = get_errno(sys_uname(buf));
5725
            if (!is_error(ret)) {
5726
                /* Overrite the native machine name with whatever is being
5727
                   emulated. */
5728
                strcpy (buf->machine, UNAME_MACHINE);
5729
                /* Allow the user to override the reported release.  */
5730
                if (qemu_uname_release && *qemu_uname_release)
5731
                  strcpy (buf->release, qemu_uname_release);
5732
            }
5733
            unlock_user_struct(buf, arg1, 1);
5734
        }
5735
        break;
5736
#ifdef TARGET_I386
5737
    case TARGET_NR_modify_ldt:
5738
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5739
        break;
5740
#if !defined(TARGET_X86_64)
5741
    case TARGET_NR_vm86old:
5742
        goto unimplemented;
5743
    case TARGET_NR_vm86:
5744
        ret = do_vm86(cpu_env, arg1, arg2);
5745
        break;
5746
#endif
5747
#endif
5748
    case TARGET_NR_adjtimex:
5749
        goto unimplemented;
5750
#ifdef TARGET_NR_create_module
5751
    case TARGET_NR_create_module:
5752
#endif
5753
    case TARGET_NR_init_module:
5754
    case TARGET_NR_delete_module:
5755
#ifdef TARGET_NR_get_kernel_syms
5756
    case TARGET_NR_get_kernel_syms:
5757
#endif
5758
        goto unimplemented;
5759
    case TARGET_NR_quotactl:
5760
        goto unimplemented;
5761
    case TARGET_NR_getpgid:
5762
        ret = get_errno(getpgid(arg1));
5763
        break;
5764
    case TARGET_NR_fchdir:
5765
        ret = get_errno(fchdir(arg1));
5766
        break;
5767
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5768
    case TARGET_NR_bdflush:
5769
        goto unimplemented;
5770
#endif
5771
#ifdef TARGET_NR_sysfs
5772
    case TARGET_NR_sysfs:
5773
        goto unimplemented;
5774
#endif
5775
    case TARGET_NR_personality:
5776
        ret = get_errno(personality(arg1));
5777
        break;
5778
#ifdef TARGET_NR_afs_syscall
5779
    case TARGET_NR_afs_syscall:
5780
        goto unimplemented;
5781
#endif
5782
#ifdef TARGET_NR__llseek /* Not on alpha */
5783
    case TARGET_NR__llseek:
5784
        {
5785
#if defined (__x86_64__)
5786
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5787
            if (put_user_s64(ret, arg4))
5788
                goto efault;
5789
#else
5790
            int64_t res;
5791
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5792
            if (put_user_s64(res, arg4))
5793
                goto efault;
5794
#endif
5795
        }
5796
        break;
5797
#endif
5798
    case TARGET_NR_getdents:
5799
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5800
        {
5801
            struct target_dirent *target_dirp;
5802
            struct linux_dirent *dirp;
5803
            abi_long count = arg3;
5804

    
5805
            dirp = malloc(count);
5806
            if (!dirp) {
5807
                ret = -TARGET_ENOMEM;
5808
                goto fail;
5809
            }
5810

    
5811
            ret = get_errno(sys_getdents(arg1, dirp, count));
5812
            if (!is_error(ret)) {
5813
                struct linux_dirent *de;
5814
                struct target_dirent *tde;
5815
                int len = ret;
5816
                int reclen, treclen;
5817
                int count1, tnamelen;
5818

    
5819
                count1 = 0;
5820
                de = dirp;
5821
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5822
                    goto efault;
5823
                tde = target_dirp;
5824
                while (len > 0) {
5825
                    reclen = de->d_reclen;
5826
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5827
                    tde->d_reclen = tswap16(treclen);
5828
                    tde->d_ino = tswapl(de->d_ino);
5829
                    tde->d_off = tswapl(de->d_off);
5830
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5831
                    if (tnamelen > 256)
5832
                        tnamelen = 256;
5833
                    /* XXX: may not be correct */
5834
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5835
                    de = (struct linux_dirent *)((char *)de + reclen);
5836
                    len -= reclen;
5837
                    tde = (struct target_dirent *)((char *)tde + treclen);
5838
                    count1 += treclen;
5839
                }
5840
                ret = count1;
5841
                unlock_user(target_dirp, arg2, ret);
5842
            }
5843
            free(dirp);
5844
        }
5845
#else
5846
        {
5847
            struct linux_dirent *dirp;
5848
            abi_long count = arg3;
5849

    
5850
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5851
                goto efault;
5852
            ret = get_errno(sys_getdents(arg1, dirp, count));
5853
            if (!is_error(ret)) {
5854
                struct linux_dirent *de;
5855
                int len = ret;
5856
                int reclen;
5857
                de = dirp;
5858
                while (len > 0) {
5859
                    reclen = de->d_reclen;
5860
                    if (reclen > len)
5861
                        break;
5862
                    de->d_reclen = tswap16(reclen);
5863
                    tswapls(&de->d_ino);
5864
                    tswapls(&de->d_off);
5865
                    de = (struct linux_dirent *)((char *)de + reclen);
5866
                    len -= reclen;
5867
                }
5868
            }
5869
            unlock_user(dirp, arg2, ret);
5870
        }
5871
#endif
5872
        break;
5873
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5874
    case TARGET_NR_getdents64:
5875
        {
5876
            struct linux_dirent64 *dirp;
5877
            abi_long count = arg3;
5878
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5879
                goto efault;
5880
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5881
            if (!is_error(ret)) {
5882
                struct linux_dirent64 *de;
5883
                int len = ret;
5884
                int reclen;
5885
                de = dirp;
5886
                while (len > 0) {
5887
                    reclen = de->d_reclen;
5888
                    if (reclen > len)
5889
                        break;
5890
                    de->d_reclen = tswap16(reclen);
5891
                    tswap64s((uint64_t *)&de->d_ino);
5892
                    tswap64s((uint64_t *)&de->d_off);
5893
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5894
                    len -= reclen;
5895
                }
5896
            }
5897
            unlock_user(dirp, arg2, ret);
5898
        }
5899
        break;
5900
#endif /* TARGET_NR_getdents64 */
5901
#ifdef TARGET_NR__newselect
5902
    case TARGET_NR__newselect:
5903
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5904
        break;
5905
#endif
5906
#ifdef TARGET_NR_poll
5907
    case TARGET_NR_poll:
5908
        {
5909
            struct target_pollfd *target_pfd;
5910
            unsigned int nfds = arg2;
5911
            int timeout = arg3;
5912
            struct pollfd *pfd;
5913
            unsigned int i;
5914

    
5915
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5916
            if (!target_pfd)
5917
                goto efault;
5918
            pfd = alloca(sizeof(struct pollfd) * nfds);
5919
            for(i = 0; i < nfds; i++) {
5920
                pfd[i].fd = tswap32(target_pfd[i].fd);
5921
                pfd[i].events = tswap16(target_pfd[i].events);
5922
            }
5923
            ret = get_errno(poll(pfd, nfds, timeout));
5924
            if (!is_error(ret)) {
5925
                for(i = 0; i < nfds; i++) {
5926
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5927
                }
5928
                ret += nfds * (sizeof(struct target_pollfd)
5929
                               - sizeof(struct pollfd));
5930
            }
5931
            unlock_user(target_pfd, arg1, ret);
5932
        }
5933
        break;
5934
#endif
5935
    case TARGET_NR_flock:
5936
        /* NOTE: the flock constant seems to be the same for every
5937
           Linux platform */
5938
        ret = get_errno(flock(arg1, arg2));
5939
        break;
5940
    case TARGET_NR_readv:
5941
        {
5942
            int count = arg3;
5943
            struct iovec *vec;
5944

    
5945
            vec = alloca(count * sizeof(struct iovec));
5946
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5947
                goto efault;
5948
            ret = get_errno(readv(arg1, vec, count));
5949
            unlock_iovec(vec, arg2, count, 1);
5950
        }
5951
        break;
5952
    case TARGET_NR_writev:
5953
        {
5954
            int count = arg3;
5955
            struct iovec *vec;
5956

    
5957
            vec = alloca(count * sizeof(struct iovec));
5958
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5959
                goto efault;
5960
            ret = get_errno(writev(arg1, vec, count));
5961
            unlock_iovec(vec, arg2, count, 0);
5962
        }
5963
        break;
5964
    case TARGET_NR_getsid:
5965
        ret = get_errno(getsid(arg1));
5966
        break;
5967
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5968
    case TARGET_NR_fdatasync:
5969
        ret = get_errno(fdatasync(arg1));
5970
        break;
5971
#endif
5972
    case TARGET_NR__sysctl:
5973
        /* We don't implement this, but ENOTDIR is always a safe
5974
           return value. */
5975
        ret = -TARGET_ENOTDIR;
5976
        break;
5977
    case TARGET_NR_sched_setparam:
5978
        {
5979
            struct sched_param *target_schp;
5980
            struct sched_param schp;
5981

    
5982
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5983
                goto efault;
5984
            schp.sched_priority = tswap32(target_schp->sched_priority);
5985
            unlock_user_struct(target_schp, arg2, 0);
5986
            ret = get_errno(sched_setparam(arg1, &schp));
5987
        }
5988
        break;
5989
    case TARGET_NR_sched_getparam:
5990
        {
5991
            struct sched_param *target_schp;
5992
            struct sched_param schp;
5993
            ret = get_errno(sched_getparam(arg1, &schp));
5994
            if (!is_error(ret)) {
5995
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5996
                    goto efault;
5997
                target_schp->sched_priority = tswap32(schp.sched_priority);
5998
                unlock_user_struct(target_schp, arg2, 1);
5999
            }
6000
        }
6001
        break;
6002
    case TARGET_NR_sched_setscheduler:
6003
        {
6004
            struct sched_param *target_schp;
6005
            struct sched_param schp;
6006
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
6007
                goto efault;
6008
            schp.sched_priority = tswap32(target_schp->sched_priority);
6009
            unlock_user_struct(target_schp, arg3, 0);
6010
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
6011
        }
6012
        break;
6013
    case TARGET_NR_sched_getscheduler:
6014
        ret = get_errno(sched_getscheduler(arg1));
6015
        break;
6016
    case TARGET_NR_sched_yield:
6017
        ret = get_errno(sched_yield());
6018
        break;
6019
    case TARGET_NR_sched_get_priority_max:
6020
        ret = get_errno(sched_get_priority_max(arg1));
6021
        break;
6022
    case TARGET_NR_sched_get_priority_min:
6023
        ret = get_errno(sched_get_priority_min(arg1));
6024
        break;
6025
    case TARGET_NR_sched_rr_get_interval:
6026
        {
6027
            struct timespec ts;
6028
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6029
            if (!is_error(ret)) {
6030
                host_to_target_timespec(arg2, &ts);
6031
            }
6032
        }
6033
        break;
6034
    case TARGET_NR_nanosleep:
6035
        {
6036
            struct timespec req, rem;
6037
            target_to_host_timespec(&req, arg1);
6038
            ret = get_errno(nanosleep(&req, &rem));
6039
            if (is_error(ret) && arg2) {
6040
                host_to_target_timespec(arg2, &rem);
6041
            }
6042
        }
6043
        break;
6044
#ifdef TARGET_NR_query_module
6045
    case TARGET_NR_query_module:
6046
        goto unimplemented;
6047
#endif
6048
#ifdef TARGET_NR_nfsservctl
6049
    case TARGET_NR_nfsservctl:
6050
        goto unimplemented;
6051
#endif
6052
    case TARGET_NR_prctl:
6053
        switch (arg1)
6054
            {
6055
            case PR_GET_PDEATHSIG:
6056
                {
6057
                    int deathsig;
6058
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6059
                    if (!is_error(ret) && arg2
6060
                        && put_user_ual(deathsig, arg2))
6061
                        goto efault;
6062
                }
6063
                break;
6064
            default:
6065
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6066
                break;
6067
            }
6068
        break;
6069
#ifdef TARGET_NR_arch_prctl
6070
    case TARGET_NR_arch_prctl:
6071
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6072
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6073
        break;
6074
#else
6075
        goto unimplemented;
6076
#endif
6077
#endif
6078
#ifdef TARGET_NR_pread
6079
    case TARGET_NR_pread:
6080
#ifdef TARGET_ARM
6081
        if (((CPUARMState *)cpu_env)->eabi)
6082
            arg4 = arg5;
6083
#endif
6084
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6085
            goto efault;
6086
        ret = get_errno(pread(arg1, p, arg3, arg4));
6087
        unlock_user(p, arg2, ret);
6088
        break;
6089
    case TARGET_NR_pwrite:
6090
#ifdef TARGET_ARM
6091
        if (((CPUARMState *)cpu_env)->eabi)
6092
            arg4 = arg5;
6093
#endif
6094
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6095
            goto efault;
6096
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6097
        unlock_user(p, arg2, 0);
6098
        break;
6099
#endif
6100
#ifdef TARGET_NR_pread64
6101
    case TARGET_NR_pread64:
6102
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6103
            goto efault;
6104
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6105
        unlock_user(p, arg2, ret);
6106
        break;
6107
    case TARGET_NR_pwrite64:
6108
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6109
            goto efault;
6110
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6111
        unlock_user(p, arg2, 0);
6112
        break;
6113
#endif
6114
    case TARGET_NR_getcwd:
6115
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6116
            goto efault;
6117
        ret = get_errno(sys_getcwd1(p, arg2));
6118
        unlock_user(p, arg1, ret);
6119
        break;
6120
    case TARGET_NR_capget:
6121
        goto unimplemented;
6122
    case TARGET_NR_capset:
6123
        goto unimplemented;
6124
    case TARGET_NR_sigaltstack:
6125
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6126
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
6127
    defined(TARGET_M68K)
6128
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6129
        break;
6130
#else
6131
        goto unimplemented;
6132
#endif
6133
    case TARGET_NR_sendfile:
6134
        goto unimplemented;
6135
#ifdef TARGET_NR_getpmsg
6136
    case TARGET_NR_getpmsg:
6137
        goto unimplemented;
6138
#endif
6139
#ifdef TARGET_NR_putpmsg
6140
    case TARGET_NR_putpmsg:
6141
        goto unimplemented;
6142
#endif
6143
#ifdef TARGET_NR_vfork
6144
    case TARGET_NR_vfork:
6145
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6146
                        0, 0, 0, 0));
6147
        break;
6148
#endif
6149
#ifdef TARGET_NR_ugetrlimit
6150
    case TARGET_NR_ugetrlimit:
6151
    {
6152
        struct rlimit rlim;
6153
        ret = get_errno(getrlimit(arg1, &rlim));
6154
        if (!is_error(ret)) {
6155
            struct target_rlimit *target_rlim;
6156
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6157
                goto efault;
6158
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6159
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
6160
            unlock_user_struct(target_rlim, arg2, 1);
6161
        }
6162
        break;
6163
    }
6164
#endif
6165
#ifdef TARGET_NR_truncate64
6166
    case TARGET_NR_truncate64:
6167
        if (!(p = lock_user_string(arg1)))
6168
            goto efault;
6169
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6170
        unlock_user(p, arg1, 0);
6171
        break;
6172
#endif
6173
#ifdef TARGET_NR_ftruncate64
6174
    case TARGET_NR_ftruncate64:
6175
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6176
        break;
6177
#endif
6178
#ifdef TARGET_NR_stat64
6179
    case TARGET_NR_stat64:
6180
        if (!(p = lock_user_string(arg1)))
6181
            goto efault;
6182
        ret = get_errno(stat(path(p), &st));
6183
        unlock_user(p, arg1, 0);
6184
        if (!is_error(ret))
6185
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6186
        break;
6187
#endif
6188
#ifdef TARGET_NR_lstat64
6189
    case TARGET_NR_lstat64:
6190
        if (!(p = lock_user_string(arg1)))
6191
            goto efault;
6192
        ret = get_errno(lstat(path(p), &st));
6193
        unlock_user(p, arg1, 0);
6194
        if (!is_error(ret))
6195
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6196
        break;
6197
#endif
6198
#ifdef TARGET_NR_fstat64
6199
    case TARGET_NR_fstat64:
6200
        ret = get_errno(fstat(arg1, &st));
6201
        if (!is_error(ret))
6202
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6203
        break;
6204
#endif
6205
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6206
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6207
#ifdef TARGET_NR_fstatat64
6208
    case TARGET_NR_fstatat64:
6209
#endif
6210
#ifdef TARGET_NR_newfstatat
6211
    case TARGET_NR_newfstatat:
6212
#endif
6213
        if (!(p = lock_user_string(arg2)))
6214
            goto efault;
6215
#ifdef __NR_fstatat64
6216
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6217
#else
6218
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6219
#endif
6220
        if (!is_error(ret))
6221
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6222
        break;
6223
#endif
6224
#ifdef USE_UID16
6225
    case TARGET_NR_lchown:
6226
        if (!(p = lock_user_string(arg1)))
6227
            goto efault;
6228
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6229
        unlock_user(p, arg1, 0);
6230
        break;
6231
    case TARGET_NR_getuid:
6232
        ret = get_errno(high2lowuid(getuid()));
6233
        break;
6234
    case TARGET_NR_getgid:
6235
        ret = get_errno(high2lowgid(getgid()));
6236
        break;
6237
    case TARGET_NR_geteuid:
6238
        ret = get_errno(high2lowuid(geteuid()));
6239
        break;
6240
    case TARGET_NR_getegid:
6241
        ret = get_errno(high2lowgid(getegid()));
6242
        break;
6243
    case TARGET_NR_setreuid:
6244
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6245
        break;
6246
    case TARGET_NR_setregid:
6247
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6248
        break;
6249
    case TARGET_NR_getgroups:
6250
        {
6251
            int gidsetsize = arg1;
6252
            uint16_t *target_grouplist;
6253
            gid_t *grouplist;
6254
            int i;
6255

    
6256
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6257
            ret = get_errno(getgroups(gidsetsize, grouplist));
6258
            if (gidsetsize == 0)
6259
                break;
6260
            if (!is_error(ret)) {
6261
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6262
                if (!target_grouplist)
6263
                    goto efault;
6264
                for(i = 0;i < ret; i++)
6265
                    target_grouplist[i] = tswap16(grouplist[i]);
6266
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6267
            }
6268
        }
6269
        break;
6270
    case TARGET_NR_setgroups:
6271
        {
6272
            int gidsetsize = arg1;
6273
            uint16_t *target_grouplist;
6274
            gid_t *grouplist;
6275
            int i;
6276

    
6277
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6278
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6279
            if (!target_grouplist) {
6280
                ret = -TARGET_EFAULT;
6281
                goto fail;
6282
            }
6283
            for(i = 0;i < gidsetsize; i++)
6284
                grouplist[i] = tswap16(target_grouplist[i]);
6285
            unlock_user(target_grouplist, arg2, 0);
6286
            ret = get_errno(setgroups(gidsetsize, grouplist));
6287
        }
6288
        break;
6289
    case TARGET_NR_fchown:
6290
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6291
        break;
6292
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6293
    case TARGET_NR_fchownat:
6294
        if (!(p = lock_user_string(arg2))) 
6295
            goto efault;
6296
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6297
        unlock_user(p, arg2, 0);
6298
        break;
6299
#endif
6300
#ifdef TARGET_NR_setresuid
6301
    case TARGET_NR_setresuid:
6302
        ret = get_errno(setresuid(low2highuid(arg1),
6303
                                  low2highuid(arg2),
6304
                                  low2highuid(arg3)));
6305
        break;
6306
#endif
6307
#ifdef TARGET_NR_getresuid
6308
    case TARGET_NR_getresuid:
6309
        {
6310
            uid_t ruid, euid, suid;
6311
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6312
            if (!is_error(ret)) {
6313
                if (put_user_u16(high2lowuid(ruid), arg1)
6314
                    || put_user_u16(high2lowuid(euid), arg2)
6315
                    || put_user_u16(high2lowuid(suid), arg3))
6316
                    goto efault;
6317
            }
6318
        }
6319
        break;
6320
#endif
6321
#ifdef TARGET_NR_getresgid
6322
    case TARGET_NR_setresgid:
6323
        ret = get_errno(setresgid(low2highgid(arg1),
6324
                                  low2highgid(arg2),
6325
                                  low2highgid(arg3)));
6326
        break;
6327
#endif
6328
#ifdef TARGET_NR_getresgid
6329
    case TARGET_NR_getresgid:
6330
        {
6331
            gid_t rgid, egid, sgid;
6332
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6333
            if (!is_error(ret)) {
6334
                if (put_user_u16(high2lowgid(rgid), arg1)
6335
                    || put_user_u16(high2lowgid(egid), arg2)
6336
                    || put_user_u16(high2lowgid(sgid), arg3))
6337
                    goto efault;
6338
            }
6339
        }
6340
        break;
6341
#endif
6342
    case TARGET_NR_chown:
6343
        if (!(p = lock_user_string(arg1)))
6344
            goto efault;
6345
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6346
        unlock_user(p, arg1, 0);
6347
        break;
6348
    case TARGET_NR_setuid:
6349
        ret = get_errno(setuid(low2highuid(arg1)));
6350
        break;
6351
    case TARGET_NR_setgid:
6352
        ret = get_errno(setgid(low2highgid(arg1)));
6353
        break;
6354
    case TARGET_NR_setfsuid:
6355
        ret = get_errno(setfsuid(arg1));
6356
        break;
6357
    case TARGET_NR_setfsgid:
6358
        ret = get_errno(setfsgid(arg1));
6359
        break;
6360
#endif /* USE_UID16 */
6361

    
6362
#ifdef TARGET_NR_lchown32
6363
    case TARGET_NR_lchown32:
6364
        if (!(p = lock_user_string(arg1)))
6365
            goto efault;
6366
        ret = get_errno(lchown(p, arg2, arg3));
6367
        unlock_user(p, arg1, 0);
6368
        break;
6369
#endif
6370
#ifdef TARGET_NR_getuid32
6371
    case TARGET_NR_getuid32:
6372
        ret = get_errno(getuid());
6373
        break;
6374
#endif
6375

    
6376
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6377
   /* Alpha specific */
6378
    case TARGET_NR_getxuid:
6379
         {
6380
            uid_t euid;
6381
            euid=geteuid();
6382
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6383
         }
6384
        ret = get_errno(getuid());
6385
        break;
6386
#endif
6387
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6388
   /* Alpha specific */
6389
    case TARGET_NR_getxgid:
6390
         {
6391
            uid_t egid;
6392
            egid=getegid();
6393
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6394
         }
6395
        ret = get_errno(getgid());
6396
        break;
6397
#endif
6398

    
6399
#ifdef TARGET_NR_getgid32
6400
    case TARGET_NR_getgid32:
6401
        ret = get_errno(getgid());
6402
        break;
6403
#endif
6404
#ifdef TARGET_NR_geteuid32
6405
    case TARGET_NR_geteuid32:
6406
        ret = get_errno(geteuid());
6407
        break;
6408
#endif
6409
#ifdef TARGET_NR_getegid32
6410
    case TARGET_NR_getegid32:
6411
        ret = get_errno(getegid());
6412
        break;
6413
#endif
6414
#ifdef TARGET_NR_setreuid32
6415
    case TARGET_NR_setreuid32:
6416
        ret = get_errno(setreuid(arg1, arg2));
6417
        break;
6418
#endif
6419
#ifdef TARGET_NR_setregid32
6420
    case TARGET_NR_setregid32:
6421
        ret = get_errno(setregid(arg1, arg2));
6422
        break;
6423
#endif
6424
#ifdef TARGET_NR_getgroups32
6425
    case TARGET_NR_getgroups32:
6426
        {
6427
            int gidsetsize = arg1;
6428
            uint32_t *target_grouplist;
6429
            gid_t *grouplist;
6430
            int i;
6431

    
6432
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6433
            ret = get_errno(getgroups(gidsetsize, grouplist));
6434
            if (gidsetsize == 0)
6435
                break;
6436
            if (!is_error(ret)) {
6437
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6438
                if (!target_grouplist) {
6439
                    ret = -TARGET_EFAULT;
6440
                    goto fail;
6441
                }
6442
                for(i = 0;i < ret; i++)
6443
                    target_grouplist[i] = tswap32(grouplist[i]);
6444
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6445
            }
6446
        }
6447
        break;
6448
#endif
6449
#ifdef TARGET_NR_setgroups32
6450
    case TARGET_NR_setgroups32:
6451
        {
6452
            int gidsetsize = arg1;
6453
            uint32_t *target_grouplist;
6454
            gid_t *grouplist;
6455
            int i;
6456

    
6457
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6458
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6459
            if (!target_grouplist) {
6460
                ret = -TARGET_EFAULT;
6461
                goto fail;
6462
            }
6463
            for(i = 0;i < gidsetsize; i++)
6464
                grouplist[i] = tswap32(target_grouplist[i]);
6465
            unlock_user(target_grouplist, arg2, 0);
6466
            ret = get_errno(setgroups(gidsetsize, grouplist));
6467
        }
6468
        break;
6469
#endif
6470
#ifdef TARGET_NR_fchown32
6471
    case TARGET_NR_fchown32:
6472
        ret = get_errno(fchown(arg1, arg2, arg3));
6473
        break;
6474
#endif
6475
#ifdef TARGET_NR_setresuid32
6476
    case TARGET_NR_setresuid32:
6477
        ret = get_errno(setresuid(arg1, arg2, arg3));
6478
        break;
6479
#endif
6480
#ifdef TARGET_NR_getresuid32
6481
    case TARGET_NR_getresuid32:
6482
        {
6483
            uid_t ruid, euid, suid;
6484
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6485
            if (!is_error(ret)) {
6486
                if (put_user_u32(ruid, arg1)
6487
                    || put_user_u32(euid, arg2)
6488
                    || put_user_u32(suid, arg3))
6489
                    goto efault;
6490
            }
6491
        }
6492
        break;
6493
#endif
6494
#ifdef TARGET_NR_setresgid32
6495
    case TARGET_NR_setresgid32:
6496
        ret = get_errno(setresgid(arg1, arg2, arg3));
6497
        break;
6498
#endif
6499
#ifdef TARGET_NR_getresgid32
6500
    case TARGET_NR_getresgid32:
6501
        {
6502
            gid_t rgid, egid, sgid;
6503
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6504
            if (!is_error(ret)) {
6505
                if (put_user_u32(rgid, arg1)
6506
                    || put_user_u32(egid, arg2)
6507
                    || put_user_u32(sgid, arg3))
6508
                    goto efault;
6509
            }
6510
        }
6511
        break;
6512
#endif
6513
#ifdef TARGET_NR_chown32
6514
    case TARGET_NR_chown32:
6515
        if (!(p = lock_user_string(arg1)))
6516
            goto efault;
6517
        ret = get_errno(chown(p, arg2, arg3));
6518
        unlock_user(p, arg1, 0);
6519
        break;
6520
#endif
6521
#ifdef TARGET_NR_setuid32
6522
    case TARGET_NR_setuid32:
6523
        ret = get_errno(setuid(arg1));
6524
        break;
6525
#endif
6526
#ifdef TARGET_NR_setgid32
6527
    case TARGET_NR_setgid32:
6528
        ret = get_errno(setgid(arg1));
6529
        break;
6530
#endif
6531
#ifdef TARGET_NR_setfsuid32
6532
    case TARGET_NR_setfsuid32:
6533
        ret = get_errno(setfsuid(arg1));
6534
        break;
6535
#endif
6536
#ifdef TARGET_NR_setfsgid32
6537
    case TARGET_NR_setfsgid32:
6538
        ret = get_errno(setfsgid(arg1));
6539
        break;
6540
#endif
6541

    
6542
    case TARGET_NR_pivot_root:
6543
        goto unimplemented;
6544
#ifdef TARGET_NR_mincore
6545
    case TARGET_NR_mincore:
6546
        {
6547
            void *a;
6548
            ret = -TARGET_EFAULT;
6549
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6550
                goto efault;
6551
            if (!(p = lock_user_string(arg3)))
6552
                goto mincore_fail;
6553
            ret = get_errno(mincore(a, arg2, p));
6554
            unlock_user(p, arg3, ret);
6555
            mincore_fail:
6556
            unlock_user(a, arg1, 0);
6557
        }
6558
        break;
6559
#endif
6560
#ifdef TARGET_NR_arm_fadvise64_64
6561
    case TARGET_NR_arm_fadvise64_64:
6562
        {
6563
                /*
6564
                 * arm_fadvise64_64 looks like fadvise64_64 but
6565
                 * with different argument order
6566
                 */
6567
                abi_long temp;
6568
                temp = arg3;
6569
                arg3 = arg4;
6570
                arg4 = temp;
6571
        }
6572
#endif
6573
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
6574
#ifdef TARGET_NR_fadvise64_64
6575
    case TARGET_NR_fadvise64_64:
6576
#endif
6577
#ifdef TARGET_NR_fadvise64
6578
    case TARGET_NR_fadvise64:
6579
#endif
6580
#ifdef TARGET_S390X
6581
        switch (arg4) {
6582
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
6583
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
6584
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
6585
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
6586
        default: break;
6587
        }
6588
#endif
6589
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
6590
        break;
6591
#endif
6592
#ifdef TARGET_NR_madvise
6593
    case TARGET_NR_madvise:
6594
        /* A straight passthrough may not be safe because qemu sometimes
6595
           turns private flie-backed mappings into anonymous mappings.
6596
           This will break MADV_DONTNEED.
6597
           This is a hint, so ignoring and returning success is ok.  */
6598
        ret = get_errno(0);
6599
        break;
6600
#endif
6601
#if TARGET_ABI_BITS == 32
6602
    case TARGET_NR_fcntl64:
6603
    {
6604
        int cmd;
6605
        struct flock64 fl;
6606
        struct target_flock64 *target_fl;
6607
#ifdef TARGET_ARM
6608
        struct target_eabi_flock64 *target_efl;
6609
#endif
6610

    
6611
        cmd = target_to_host_fcntl_cmd(arg2);
6612
        if (cmd == -TARGET_EINVAL)
6613
                return cmd;
6614

    
6615
        switch(arg2) {
6616
        case TARGET_F_GETLK64:
6617
#ifdef TARGET_ARM
6618
            if (((CPUARMState *)cpu_env)->eabi) {
6619
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6620
                    goto efault;
6621
                fl.l_type = tswap16(target_efl->l_type);
6622
                fl.l_whence = tswap16(target_efl->l_whence);
6623
                fl.l_start = tswap64(target_efl->l_start);
6624
                fl.l_len = tswap64(target_efl->l_len);
6625
                fl.l_pid = tswap32(target_efl->l_pid);
6626
                unlock_user_struct(target_efl, arg3, 0);
6627
            } else
6628
#endif
6629
            {
6630
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6631
                    goto efault;
6632
                fl.l_type = tswap16(target_fl->l_type);
6633
                fl.l_whence = tswap16(target_fl->l_whence);
6634
                fl.l_start = tswap64(target_fl->l_start);
6635
                fl.l_len = tswap64(target_fl->l_len);
6636
                fl.l_pid = tswap32(target_fl->l_pid);
6637
                unlock_user_struct(target_fl, arg3, 0);
6638
            }
6639
            ret = get_errno(fcntl(arg1, cmd, &fl));
6640
            if (ret == 0) {
6641
#ifdef TARGET_ARM
6642
                if (((CPUARMState *)cpu_env)->eabi) {
6643
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6644
                        goto efault;
6645
                    target_efl->l_type = tswap16(fl.l_type);
6646
                    target_efl->l_whence = tswap16(fl.l_whence);
6647
                    target_efl->l_start = tswap64(fl.l_start);
6648
                    target_efl->l_len = tswap64(fl.l_len);
6649
                    target_efl->l_pid = tswap32(fl.l_pid);
6650
                    unlock_user_struct(target_efl, arg3, 1);
6651
                } else
6652
#endif
6653
                {
6654
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6655
                        goto efault;
6656
                    target_fl->l_type = tswap16(fl.l_type);
6657
                    target_fl->l_whence = tswap16(fl.l_whence);
6658
                    target_fl->l_start = tswap64(fl.l_start);
6659
                    target_fl->l_len = tswap64(fl.l_len);
6660
                    target_fl->l_pid = tswap32(fl.l_pid);
6661
                    unlock_user_struct(target_fl, arg3, 1);
6662
                }
6663
            }
6664
            break;
6665

    
6666
        case TARGET_F_SETLK64:
6667
        case TARGET_F_SETLKW64:
6668
#ifdef TARGET_ARM
6669
            if (((CPUARMState *)cpu_env)->eabi) {
6670
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6671
                    goto efault;
6672
                fl.l_type = tswap16(target_efl->l_type);
6673
                fl.l_whence = tswap16(target_efl->l_whence);
6674
                fl.l_start = tswap64(target_efl->l_start);
6675
                fl.l_len = tswap64(target_efl->l_len);
6676
                fl.l_pid = tswap32(target_efl->l_pid);
6677
                unlock_user_struct(target_efl, arg3, 0);
6678
            } else
6679
#endif
6680
            {
6681
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6682
                    goto efault;
6683
                fl.l_type = tswap16(target_fl->l_type);
6684
                fl.l_whence = tswap16(target_fl->l_whence);
6685
                fl.l_start = tswap64(target_fl->l_start);
6686
                fl.l_len = tswap64(target_fl->l_len);
6687
                fl.l_pid = tswap32(target_fl->l_pid);
6688
                unlock_user_struct(target_fl, arg3, 0);
6689
            }
6690
            ret = get_errno(fcntl(arg1, cmd, &fl));
6691
            break;
6692
        default:
6693
            ret = do_fcntl(arg1, arg2, arg3);
6694
            break;
6695
        }
6696
        break;
6697
    }
6698
#endif
6699
#ifdef TARGET_NR_cacheflush
6700
    case TARGET_NR_cacheflush:
6701
        /* self-modifying code is handled automatically, so nothing needed */
6702
        ret = 0;
6703
        break;
6704
#endif
6705
#ifdef TARGET_NR_security
6706
    case TARGET_NR_security:
6707
        goto unimplemented;
6708
#endif
6709
#ifdef TARGET_NR_getpagesize
6710
    case TARGET_NR_getpagesize:
6711
        ret = TARGET_PAGE_SIZE;
6712
        break;
6713
#endif
6714
    case TARGET_NR_gettid:
6715
        ret = get_errno(gettid());
6716
        break;
6717
#ifdef TARGET_NR_readahead
6718
    case TARGET_NR_readahead:
6719
#if TARGET_ABI_BITS == 32
6720
#ifdef TARGET_ARM
6721
        if (((CPUARMState *)cpu_env)->eabi)
6722
        {
6723
            arg2 = arg3;
6724
            arg3 = arg4;
6725
            arg4 = arg5;
6726
        }
6727
#endif
6728
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6729
#else
6730
        ret = get_errno(readahead(arg1, arg2, arg3));
6731
#endif
6732
        break;
6733
#endif
6734
#ifdef TARGET_NR_setxattr
6735
    case TARGET_NR_setxattr:
6736
    case TARGET_NR_lsetxattr:
6737
    case TARGET_NR_fsetxattr:
6738
    case TARGET_NR_getxattr:
6739
    case TARGET_NR_lgetxattr:
6740
    case TARGET_NR_fgetxattr:
6741
    case TARGET_NR_listxattr:
6742
    case TARGET_NR_llistxattr:
6743
    case TARGET_NR_flistxattr:
6744
    case TARGET_NR_removexattr:
6745
    case TARGET_NR_lremovexattr:
6746
    case TARGET_NR_fremovexattr:
6747
        ret = -TARGET_EOPNOTSUPP;
6748
        break;
6749
#endif
6750
#ifdef TARGET_NR_set_thread_area
6751
    case TARGET_NR_set_thread_area:
6752
#if defined(TARGET_MIPS)
6753
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6754
      ret = 0;
6755
      break;
6756
#elif defined(TARGET_CRIS)
6757
      if (arg1 & 0xff)
6758
          ret = -TARGET_EINVAL;
6759
      else {
6760
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6761
          ret = 0;
6762
      }
6763
      break;
6764
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6765
      ret = do_set_thread_area(cpu_env, arg1);
6766
      break;
6767
#else
6768
      goto unimplemented_nowarn;
6769
#endif
6770
#endif
6771
#ifdef TARGET_NR_get_thread_area
6772
    case TARGET_NR_get_thread_area:
6773
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6774
        ret = do_get_thread_area(cpu_env, arg1);
6775
#else
6776
        goto unimplemented_nowarn;
6777
#endif
6778
#endif
6779
#ifdef TARGET_NR_getdomainname
6780
    case TARGET_NR_getdomainname:
6781
        goto unimplemented_nowarn;
6782
#endif
6783

    
6784
#ifdef TARGET_NR_clock_gettime
6785
    case TARGET_NR_clock_gettime:
6786
    {
6787
        struct timespec ts;
6788
        ret = get_errno(clock_gettime(arg1, &ts));
6789
        if (!is_error(ret)) {
6790
            host_to_target_timespec(arg2, &ts);
6791
        }
6792
        break;
6793
    }
6794
#endif
6795
#ifdef TARGET_NR_clock_getres
6796
    case TARGET_NR_clock_getres:
6797
    {
6798
        struct timespec ts;
6799
        ret = get_errno(clock_getres(arg1, &ts));
6800
        if (!is_error(ret)) {
6801
            host_to_target_timespec(arg2, &ts);
6802
        }
6803
        break;
6804
    }
6805
#endif
6806
#ifdef TARGET_NR_clock_nanosleep
6807
    case TARGET_NR_clock_nanosleep:
6808
    {
6809
        struct timespec ts;
6810
        target_to_host_timespec(&ts, arg3);
6811
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6812
        if (arg4)
6813
            host_to_target_timespec(arg4, &ts);
6814
        break;
6815
    }
6816
#endif
6817

    
6818
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6819
    case TARGET_NR_set_tid_address:
6820
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6821
        break;
6822
#endif
6823

    
6824
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6825
    case TARGET_NR_tkill:
6826
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6827
        break;
6828
#endif
6829

    
6830
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6831
    case TARGET_NR_tgkill:
6832
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6833
                        target_to_host_signal(arg3)));
6834
        break;
6835
#endif
6836

    
6837
#ifdef TARGET_NR_set_robust_list
6838
    case TARGET_NR_set_robust_list:
6839
        goto unimplemented_nowarn;
6840
#endif
6841

    
6842
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6843
    case TARGET_NR_utimensat:
6844
        {
6845
            struct timespec *tsp, ts[2];
6846
            if (!arg3) {
6847
                tsp = NULL;
6848
            } else {
6849
                target_to_host_timespec(ts, arg3);
6850
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6851
                tsp = ts;
6852
            }
6853
            if (!arg2)
6854
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6855
            else {
6856
                if (!(p = lock_user_string(arg2))) {
6857
                    ret = -TARGET_EFAULT;
6858
                    goto fail;
6859
                }
6860
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6861
                unlock_user(p, arg2, 0);
6862
            }
6863
        }
6864
        break;
6865
#endif
6866
#if defined(CONFIG_USE_NPTL)
6867
    case TARGET_NR_futex:
6868
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6869
        break;
6870
#endif
6871
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6872
    case TARGET_NR_inotify_init:
6873
        ret = get_errno(sys_inotify_init());
6874
        break;
6875
#endif
6876
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6877
    case TARGET_NR_inotify_add_watch:
6878
        p = lock_user_string(arg2);
6879
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6880
        unlock_user(p, arg2, 0);
6881
        break;
6882
#endif
6883
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6884
    case TARGET_NR_inotify_rm_watch:
6885
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6886
        break;
6887
#endif
6888

    
6889
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
6890
    case TARGET_NR_mq_open:
6891
        {
6892
            struct mq_attr posix_mq_attr;
6893

    
6894
            p = lock_user_string(arg1 - 1);
6895
            if (arg4 != 0)
6896
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6897
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6898
            unlock_user (p, arg1, 0);
6899
        }
6900
        break;
6901

    
6902
    case TARGET_NR_mq_unlink:
6903
        p = lock_user_string(arg1 - 1);
6904
        ret = get_errno(mq_unlink(p));
6905
        unlock_user (p, arg1, 0);
6906
        break;
6907

    
6908
    case TARGET_NR_mq_timedsend:
6909
        {
6910
            struct timespec ts;
6911

    
6912
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6913
            if (arg5 != 0) {
6914
                target_to_host_timespec(&ts, arg5);
6915
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6916
                host_to_target_timespec(arg5, &ts);
6917
            }
6918
            else
6919
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6920
            unlock_user (p, arg2, arg3);
6921
        }
6922
        break;
6923

    
6924
    case TARGET_NR_mq_timedreceive:
6925
        {
6926
            struct timespec ts;
6927
            unsigned int prio;
6928

    
6929
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6930
            if (arg5 != 0) {
6931
                target_to_host_timespec(&ts, arg5);
6932
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6933
                host_to_target_timespec(arg5, &ts);
6934
            }
6935
            else
6936
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6937
            unlock_user (p, arg2, arg3);
6938
            if (arg4 != 0)
6939
                put_user_u32(prio, arg4);
6940
        }
6941
        break;
6942

    
6943
    /* Not implemented for now... */
6944
/*     case TARGET_NR_mq_notify: */
6945
/*         break; */
6946

    
6947
    case TARGET_NR_mq_getsetattr:
6948
        {
6949
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6950
            ret = 0;
6951
            if (arg3 != 0) {
6952
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6953
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6954
            }
6955
            if (arg2 != 0) {
6956
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6957
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6958
            }
6959

    
6960
        }
6961
        break;
6962
#endif
6963

    
6964
#ifdef CONFIG_SPLICE
6965
#ifdef TARGET_NR_tee
6966
    case TARGET_NR_tee:
6967
        {
6968
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
6969
        }
6970
        break;
6971
#endif
6972
#ifdef TARGET_NR_splice
6973
    case TARGET_NR_splice:
6974
        {
6975
            loff_t loff_in, loff_out;
6976
            loff_t *ploff_in = NULL, *ploff_out = NULL;
6977
            if(arg2) {
6978
                get_user_u64(loff_in, arg2);
6979
                ploff_in = &loff_in;
6980
            }
6981
            if(arg4) {
6982
                get_user_u64(loff_out, arg2);
6983
                ploff_out = &loff_out;
6984
            }
6985
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
6986
        }
6987
        break;
6988
#endif
6989
#ifdef TARGET_NR_vmsplice
6990
        case TARGET_NR_vmsplice:
6991
        {
6992
            int count = arg3;
6993
            struct iovec *vec;
6994

    
6995
            vec = alloca(count * sizeof(struct iovec));
6996
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6997
                goto efault;
6998
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
6999
            unlock_iovec(vec, arg2, count, 0);
7000
        }
7001
        break;
7002
#endif
7003
#endif /* CONFIG_SPLICE */
7004
#ifdef CONFIG_EVENTFD
7005
#if defined(TARGET_NR_eventfd)
7006
    case TARGET_NR_eventfd:
7007
        ret = get_errno(eventfd(arg1, 0));
7008
        break;
7009
#endif
7010
#if defined(TARGET_NR_eventfd2)
7011
    case TARGET_NR_eventfd2:
7012
        ret = get_errno(eventfd(arg1, arg2));
7013
        break;
7014
#endif
7015
#endif /* CONFIG_EVENTFD  */
7016
    default:
7017
    unimplemented:
7018
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7019
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7020
    unimplemented_nowarn:
7021
#endif
7022
        ret = -TARGET_ENOSYS;
7023
        break;
7024
    }
7025
fail:
7026
#ifdef DEBUG
7027
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7028
#endif
7029
    if(do_strace)
7030
        print_syscall_ret(num, ret);
7031
    return ret;
7032
efault:
7033
    ret = -TARGET_EFAULT;
7034
    goto fail;
7035
}