Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 97374d38

History | View | Annotate | Download (225 kB)

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

    
70
#define termios host_termios
71
#define winsize host_winsize
72
#define termio host_termio
73
#define sgttyb host_sgttyb /* same as target */
74
#define tchars host_tchars /* same as target */
75
#define ltchars host_ltchars /* same as target */
76

    
77
#include <linux/termios.h>
78
#include <linux/unistd.h>
79
#include <linux/utsname.h>
80
#include <linux/cdrom.h>
81
#include <linux/hdreg.h>
82
#include <linux/soundcard.h>
83
#include <linux/kd.h>
84
#include <linux/mtio.h>
85
#include <linux/fs.h>
86
#include <linux/fb.h>
87
#include <linux/vt.h>
88
#include "linux_loop.h"
89
#include "cpu-uname.h"
90

    
91
#include "qemu.h"
92
#include "qemu-common.h"
93

    
94
#if defined(CONFIG_USE_NPTL)
95
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
96
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
97
#else
98
/* XXX: Hardcode the above values.  */
99
#define CLONE_NPTL_FLAGS2 0
100
#endif
101

    
102
//#define DEBUG
103

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

    
108

    
109
#undef _syscall0
110
#undef _syscall1
111
#undef _syscall2
112
#undef _syscall3
113
#undef _syscall4
114
#undef _syscall5
115
#undef _syscall6
116

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

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

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

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

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

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

    
154

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

    
163

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

    
193
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
194
#define __NR__llseek __NR_lseek
195
#endif
196

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

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

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

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

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

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

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

    
287
#undef COPY_UTSNAME_FIELD
288
}
289

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

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

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

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

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

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

    
474
#endif /* CONFIG_ATFILE */
475

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

    
492
#ifdef CONFIG_INOTIFY
493
#include <sys/inotify.h>
494

    
495
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
496
static int sys_inotify_init(void)
497
{
498
  return (inotify_init());
499
}
500
#endif
501
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
502
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
503
{
504
  return (inotify_add_watch(fd, pathname, mask));
505
}
506
#endif
507
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
508
static int sys_inotify_rm_watch(int fd, int32_t wd)
509
{
510
  return (inotify_rm_watch(fd, wd));
511
}
512
#endif
513
#ifdef CONFIG_INOTIFY1
514
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
515
static int sys_inotify_init1(int flags)
516
{
517
  return (inotify_init1(flags));
518
}
519
#endif
520
#endif
521
#else
522
/* Userspace can usually survive runtime without inotify */
523
#undef TARGET_NR_inotify_init
524
#undef TARGET_NR_inotify_init1
525
#undef TARGET_NR_inotify_add_watch
526
#undef TARGET_NR_inotify_rm_watch
527
#endif /* CONFIG_INOTIFY  */
528

    
529

    
530
extern int personality(int);
531
extern int flock(int, int);
532
extern int setfsuid(int);
533
extern int setfsgid(int);
534
extern int setgroups(int, gid_t *);
535

    
536
#define ERRNO_TABLE_SIZE 1200
537

    
538
/* target_to_host_errno_table[] is initialized from
539
 * host_to_target_errno_table[] in syscall_init(). */
540
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
541
};
542

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

    
655
static inline int host_to_target_errno(int err)
656
{
657
    if(host_to_target_errno_table[err])
658
        return host_to_target_errno_table[err];
659
    return err;
660
}
661

    
662
static inline int target_to_host_errno(int err)
663
{
664
    if (target_to_host_errno_table[err])
665
        return target_to_host_errno_table[err];
666
    return err;
667
}
668

    
669
static inline abi_long get_errno(abi_long ret)
670
{
671
    if (ret == -1)
672
        return -host_to_target_errno(errno);
673
    else
674
        return ret;
675
}
676

    
677
static inline int is_error(abi_long ret)
678
{
679
    return (abi_ulong)ret >= (abi_ulong)(-4096);
680
}
681

    
682
char *target_strerror(int err)
683
{
684
    return strerror(target_to_host_errno(err));
685
}
686

    
687
static abi_ulong target_brk;
688
static abi_ulong target_original_brk;
689

    
690
void target_set_brk(abi_ulong new_brk)
691
{
692
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
693
}
694

    
695
/* do_brk() must return target values and target errnos. */
696
abi_long do_brk(abi_ulong new_brk)
697
{
698
    abi_ulong brk_page;
699
    abi_long mapped_addr;
700
    int        new_alloc_size;
701

    
702
    if (!new_brk)
703
        return target_brk;
704
    if (new_brk < target_original_brk)
705
        return target_brk;
706

    
707
    brk_page = HOST_PAGE_ALIGN(target_brk);
708

    
709
    /* If the new brk is less than this, set it and we're done... */
710
    if (new_brk < brk_page) {
711
        target_brk = new_brk;
712
            return target_brk;
713
    }
714

    
715
    /* We need to allocate more memory after the brk... */
716
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
717
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
718
                                        PROT_READ|PROT_WRITE,
719
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
720

    
721
#if defined(TARGET_ALPHA)
722
    /* We (partially) emulate OSF/1 on Alpha, which requires we
723
       return a proper errno, not an unchanged brk value.  */
724
    if (is_error(mapped_addr)) {
725
        return -TARGET_ENOMEM;
726
    }
727
#endif
728

    
729
    if (!is_error(mapped_addr)) {
730
        target_brk = new_brk;
731
    }
732
    return target_brk;
733
}
734

    
735
static inline abi_long copy_from_user_fdset(fd_set *fds,
736
                                            abi_ulong target_fds_addr,
737
                                            int n)
738
{
739
    int i, nw, j, k;
740
    abi_ulong b, *target_fds;
741

    
742
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
743
    if (!(target_fds = lock_user(VERIFY_READ,
744
                                 target_fds_addr,
745
                                 sizeof(abi_ulong) * nw,
746
                                 1)))
747
        return -TARGET_EFAULT;
748

    
749
    FD_ZERO(fds);
750
    k = 0;
751
    for (i = 0; i < nw; i++) {
752
        /* grab the abi_ulong */
753
        __get_user(b, &target_fds[i]);
754
        for (j = 0; j < TARGET_ABI_BITS; j++) {
755
            /* check the bit inside the abi_ulong */
756
            if ((b >> j) & 1)
757
                FD_SET(k, fds);
758
            k++;
759
        }
760
    }
761

    
762
    unlock_user(target_fds, target_fds_addr, 0);
763

    
764
    return 0;
765
}
766

    
767
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
768
                                          const fd_set *fds,
769
                                          int n)
770
{
771
    int i, nw, j, k;
772
    abi_long v;
773
    abi_ulong *target_fds;
774

    
775
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
776
    if (!(target_fds = lock_user(VERIFY_WRITE,
777
                                 target_fds_addr,
778
                                 sizeof(abi_ulong) * nw,
779
                                 0)))
780
        return -TARGET_EFAULT;
781

    
782
    k = 0;
783
    for (i = 0; i < nw; i++) {
784
        v = 0;
785
        for (j = 0; j < TARGET_ABI_BITS; j++) {
786
            v |= ((FD_ISSET(k, fds) != 0) << j);
787
            k++;
788
        }
789
        __put_user(v, &target_fds[i]);
790
    }
791

    
792
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
793

    
794
    return 0;
795
}
796

    
797
#if defined(__alpha__)
798
#define HOST_HZ 1024
799
#else
800
#define HOST_HZ 100
801
#endif
802

    
803
static inline abi_long host_to_target_clock_t(long ticks)
804
{
805
#if HOST_HZ == TARGET_HZ
806
    return ticks;
807
#else
808
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
809
#endif
810
}
811

    
812
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
813
                                             const struct rusage *rusage)
814
{
815
    struct target_rusage *target_rusage;
816

    
817
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
818
        return -TARGET_EFAULT;
819
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
820
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
821
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
822
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
823
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
824
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
825
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
826
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
827
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
828
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
829
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
830
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
831
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
832
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
833
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
834
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
835
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
836
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
837
    unlock_user_struct(target_rusage, target_addr, 1);
838

    
839
    return 0;
840
}
841

    
842
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
843
{
844
    if (target_rlim == TARGET_RLIM_INFINITY)
845
        return RLIM_INFINITY;
846
    else
847
        return tswapl(target_rlim);
848
}
849

    
850
static inline target_ulong host_to_target_rlim(rlim_t rlim)
851
{
852
    if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
853
        return TARGET_RLIM_INFINITY;
854
    else
855
        return tswapl(rlim);
856
}
857

    
858
static inline abi_long copy_from_user_timeval(struct timeval *tv,
859
                                              abi_ulong target_tv_addr)
860
{
861
    struct target_timeval *target_tv;
862

    
863
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
864
        return -TARGET_EFAULT;
865

    
866
    __get_user(tv->tv_sec, &target_tv->tv_sec);
867
    __get_user(tv->tv_usec, &target_tv->tv_usec);
868

    
869
    unlock_user_struct(target_tv, target_tv_addr, 0);
870

    
871
    return 0;
872
}
873

    
874
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
875
                                            const struct timeval *tv)
876
{
877
    struct target_timeval *target_tv;
878

    
879
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
880
        return -TARGET_EFAULT;
881

    
882
    __put_user(tv->tv_sec, &target_tv->tv_sec);
883
    __put_user(tv->tv_usec, &target_tv->tv_usec);
884

    
885
    unlock_user_struct(target_tv, target_tv_addr, 1);
886

    
887
    return 0;
888
}
889

    
890
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
891
#include <mqueue.h>
892

    
893
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
894
                                              abi_ulong target_mq_attr_addr)
895
{
896
    struct target_mq_attr *target_mq_attr;
897

    
898
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
899
                          target_mq_attr_addr, 1))
900
        return -TARGET_EFAULT;
901

    
902
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
903
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
904
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
905
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
906

    
907
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
908

    
909
    return 0;
910
}
911

    
912
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
913
                                            const struct mq_attr *attr)
914
{
915
    struct target_mq_attr *target_mq_attr;
916

    
917
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
918
                          target_mq_attr_addr, 0))
919
        return -TARGET_EFAULT;
920

    
921
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
922
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
923
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
924
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
925

    
926
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
927

    
928
    return 0;
929
}
930
#endif
931

    
932
/* do_select() must return target values and target errnos. */
933
static abi_long do_select(int n,
934
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
935
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
936
{
937
    fd_set rfds, wfds, efds;
938
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
939
    struct timeval tv, *tv_ptr;
940
    abi_long ret;
941

    
942
    if (rfd_addr) {
943
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
944
            return -TARGET_EFAULT;
945
        rfds_ptr = &rfds;
946
    } else {
947
        rfds_ptr = NULL;
948
    }
949
    if (wfd_addr) {
950
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
951
            return -TARGET_EFAULT;
952
        wfds_ptr = &wfds;
953
    } else {
954
        wfds_ptr = NULL;
955
    }
956
    if (efd_addr) {
957
        if (copy_from_user_fdset(&efds, efd_addr, n))
958
            return -TARGET_EFAULT;
959
        efds_ptr = &efds;
960
    } else {
961
        efds_ptr = NULL;
962
    }
963

    
964
    if (target_tv_addr) {
965
        if (copy_from_user_timeval(&tv, target_tv_addr))
966
            return -TARGET_EFAULT;
967
        tv_ptr = &tv;
968
    } else {
969
        tv_ptr = NULL;
970
    }
971

    
972
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
973

    
974
    if (!is_error(ret)) {
975
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
976
            return -TARGET_EFAULT;
977
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
978
            return -TARGET_EFAULT;
979
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
980
            return -TARGET_EFAULT;
981

    
982
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
983
            return -TARGET_EFAULT;
984
    }
985

    
986
    return ret;
987
}
988

    
989
static abi_long do_pipe2(int host_pipe[], int flags)
990
{
991
#ifdef CONFIG_PIPE2
992
    return pipe2(host_pipe, flags);
993
#else
994
    return -ENOSYS;
995
#endif
996
}
997

    
998
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
999
                        int flags, int is_pipe2)
1000
{
1001
    int host_pipe[2];
1002
    abi_long ret;
1003
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1004

    
1005
    if (is_error(ret))
1006
        return get_errno(ret);
1007

    
1008
    /* Several targets have special calling conventions for the original
1009
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1010
    if (!is_pipe2) {
1011
#if defined(TARGET_ALPHA)
1012
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1013
        return host_pipe[0];
1014
#elif defined(TARGET_MIPS)
1015
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1016
        return host_pipe[0];
1017
#elif defined(TARGET_SH4)
1018
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1019
        return host_pipe[0];
1020
#endif
1021
    }
1022

    
1023
    if (put_user_s32(host_pipe[0], pipedes)
1024
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1025
        return -TARGET_EFAULT;
1026
    return get_errno(ret);
1027
}
1028

    
1029
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1030
                                              abi_ulong target_addr,
1031
                                              socklen_t len)
1032
{
1033
    struct target_ip_mreqn *target_smreqn;
1034

    
1035
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1036
    if (!target_smreqn)
1037
        return -TARGET_EFAULT;
1038
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1039
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1040
    if (len == sizeof(struct target_ip_mreqn))
1041
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1042
    unlock_user(target_smreqn, target_addr, 0);
1043

    
1044
    return 0;
1045
}
1046

    
1047
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1048
                                               abi_ulong target_addr,
1049
                                               socklen_t len)
1050
{
1051
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1052
    sa_family_t sa_family;
1053
    struct target_sockaddr *target_saddr;
1054

    
1055
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1056
    if (!target_saddr)
1057
        return -TARGET_EFAULT;
1058

    
1059
    sa_family = tswap16(target_saddr->sa_family);
1060

    
1061
    /* Oops. The caller might send a incomplete sun_path; sun_path
1062
     * must be terminated by \0 (see the manual page), but
1063
     * unfortunately it is quite common to specify sockaddr_un
1064
     * length as "strlen(x->sun_path)" while it should be
1065
     * "strlen(...) + 1". We'll fix that here if needed.
1066
     * Linux kernel has a similar feature.
1067
     */
1068

    
1069
    if (sa_family == AF_UNIX) {
1070
        if (len < unix_maxlen && len > 0) {
1071
            char *cp = (char*)target_saddr;
1072

    
1073
            if ( cp[len-1] && !cp[len] )
1074
                len++;
1075
        }
1076
        if (len > unix_maxlen)
1077
            len = unix_maxlen;
1078
    }
1079

    
1080
    memcpy(addr, target_saddr, len);
1081
    addr->sa_family = sa_family;
1082
    unlock_user(target_saddr, target_addr, 0);
1083

    
1084
    return 0;
1085
}
1086

    
1087
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1088
                                               struct sockaddr *addr,
1089
                                               socklen_t len)
1090
{
1091
    struct target_sockaddr *target_saddr;
1092

    
1093
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1094
    if (!target_saddr)
1095
        return -TARGET_EFAULT;
1096
    memcpy(target_saddr, addr, len);
1097
    target_saddr->sa_family = tswap16(addr->sa_family);
1098
    unlock_user(target_saddr, target_addr, len);
1099

    
1100
    return 0;
1101
}
1102

    
1103
/* ??? Should this also swap msgh->name?  */
1104
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1105
                                           struct target_msghdr *target_msgh)
1106
{
1107
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1108
    abi_long msg_controllen;
1109
    abi_ulong target_cmsg_addr;
1110
    struct target_cmsghdr *target_cmsg;
1111
    socklen_t space = 0;
1112
    
1113
    msg_controllen = tswapl(target_msgh->msg_controllen);
1114
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1115
        goto the_end;
1116
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1117
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1118
    if (!target_cmsg)
1119
        return -TARGET_EFAULT;
1120

    
1121
    while (cmsg && target_cmsg) {
1122
        void *data = CMSG_DATA(cmsg);
1123
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1124

    
1125
        int len = tswapl(target_cmsg->cmsg_len)
1126
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1127

    
1128
        space += CMSG_SPACE(len);
1129
        if (space > msgh->msg_controllen) {
1130
            space -= CMSG_SPACE(len);
1131
            gemu_log("Host cmsg overflow\n");
1132
            break;
1133
        }
1134

    
1135
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1136
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1137
        cmsg->cmsg_len = CMSG_LEN(len);
1138

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

    
1147
            for (i = 0; i < numfds; i++)
1148
                fd[i] = tswap32(target_fd[i]);
1149
        }
1150

    
1151
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1152
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1153
    }
1154
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1155
 the_end:
1156
    msgh->msg_controllen = space;
1157
    return 0;
1158
}
1159

    
1160
/* ??? Should this also swap msgh->name?  */
1161
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1162
                                           struct msghdr *msgh)
1163
{
1164
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1165
    abi_long msg_controllen;
1166
    abi_ulong target_cmsg_addr;
1167
    struct target_cmsghdr *target_cmsg;
1168
    socklen_t space = 0;
1169

    
1170
    msg_controllen = tswapl(target_msgh->msg_controllen);
1171
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1172
        goto the_end;
1173
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1174
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1175
    if (!target_cmsg)
1176
        return -TARGET_EFAULT;
1177

    
1178
    while (cmsg && target_cmsg) {
1179
        void *data = CMSG_DATA(cmsg);
1180
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1181

    
1182
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1183

    
1184
        space += TARGET_CMSG_SPACE(len);
1185
        if (space > msg_controllen) {
1186
            space -= TARGET_CMSG_SPACE(len);
1187
            gemu_log("Target cmsg overflow\n");
1188
            break;
1189
        }
1190

    
1191
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1192
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1193
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1194

    
1195
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1196
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1197
            memcpy(target_data, data, len);
1198
        } else {
1199
            int *fd = (int *)data;
1200
            int *target_fd = (int *)target_data;
1201
            int i, numfds = len / sizeof(int);
1202

    
1203
            for (i = 0; i < numfds; i++)
1204
                target_fd[i] = tswap32(fd[i]);
1205
        }
1206

    
1207
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1208
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1209
    }
1210
    unlock_user(target_cmsg, target_cmsg_addr, space);
1211
 the_end:
1212
    target_msgh->msg_controllen = tswapl(space);
1213
    return 0;
1214
}
1215

    
1216
/* do_setsockopt() Must return target values and target errnos. */
1217
static abi_long do_setsockopt(int sockfd, int level, int optname,
1218
                              abi_ulong optval_addr, socklen_t optlen)
1219
{
1220
    abi_long ret;
1221
    int val;
1222
    struct ip_mreqn *ip_mreq;
1223
    struct ip_mreq_source *ip_mreq_source;
1224

    
1225
    switch(level) {
1226
    case SOL_TCP:
1227
        /* TCP options all take an 'int' value.  */
1228
        if (optlen < sizeof(uint32_t))
1229
            return -TARGET_EINVAL;
1230

    
1231
        if (get_user_u32(val, optval_addr))
1232
            return -TARGET_EFAULT;
1233
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1234
        break;
1235
    case SOL_IP:
1236
        switch(optname) {
1237
        case IP_TOS:
1238
        case IP_TTL:
1239
        case IP_HDRINCL:
1240
        case IP_ROUTER_ALERT:
1241
        case IP_RECVOPTS:
1242
        case IP_RETOPTS:
1243
        case IP_PKTINFO:
1244
        case IP_MTU_DISCOVER:
1245
        case IP_RECVERR:
1246
        case IP_RECVTOS:
1247
#ifdef IP_FREEBIND
1248
        case IP_FREEBIND:
1249
#endif
1250
        case IP_MULTICAST_TTL:
1251
        case IP_MULTICAST_LOOP:
1252
            val = 0;
1253
            if (optlen >= sizeof(uint32_t)) {
1254
                if (get_user_u32(val, optval_addr))
1255
                    return -TARGET_EFAULT;
1256
            } else if (optlen >= 1) {
1257
                if (get_user_u8(val, optval_addr))
1258
                    return -TARGET_EFAULT;
1259
            }
1260
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1261
            break;
1262
        case IP_ADD_MEMBERSHIP:
1263
        case IP_DROP_MEMBERSHIP:
1264
            if (optlen < sizeof (struct target_ip_mreq) ||
1265
                optlen > sizeof (struct target_ip_mreqn))
1266
                return -TARGET_EINVAL;
1267

    
1268
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1269
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1270
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1271
            break;
1272

    
1273
        case IP_BLOCK_SOURCE:
1274
        case IP_UNBLOCK_SOURCE:
1275
        case IP_ADD_SOURCE_MEMBERSHIP:
1276
        case IP_DROP_SOURCE_MEMBERSHIP:
1277
            if (optlen != sizeof (struct target_ip_mreq_source))
1278
                return -TARGET_EINVAL;
1279

    
1280
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1281
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1282
            unlock_user (ip_mreq_source, optval_addr, 0);
1283
            break;
1284

    
1285
        default:
1286
            goto unimplemented;
1287
        }
1288
        break;
1289
    case TARGET_SOL_SOCKET:
1290
        switch (optname) {
1291
            /* Options with 'int' argument.  */
1292
        case TARGET_SO_DEBUG:
1293
                optname = SO_DEBUG;
1294
                break;
1295
        case TARGET_SO_REUSEADDR:
1296
                optname = SO_REUSEADDR;
1297
                break;
1298
        case TARGET_SO_TYPE:
1299
                optname = SO_TYPE;
1300
                break;
1301
        case TARGET_SO_ERROR:
1302
                optname = SO_ERROR;
1303
                break;
1304
        case TARGET_SO_DONTROUTE:
1305
                optname = SO_DONTROUTE;
1306
                break;
1307
        case TARGET_SO_BROADCAST:
1308
                optname = SO_BROADCAST;
1309
                break;
1310
        case TARGET_SO_SNDBUF:
1311
                optname = SO_SNDBUF;
1312
                break;
1313
        case TARGET_SO_RCVBUF:
1314
                optname = SO_RCVBUF;
1315
                break;
1316
        case TARGET_SO_KEEPALIVE:
1317
                optname = SO_KEEPALIVE;
1318
                break;
1319
        case TARGET_SO_OOBINLINE:
1320
                optname = SO_OOBINLINE;
1321
                break;
1322
        case TARGET_SO_NO_CHECK:
1323
                optname = SO_NO_CHECK;
1324
                break;
1325
        case TARGET_SO_PRIORITY:
1326
                optname = SO_PRIORITY;
1327
                break;
1328
#ifdef SO_BSDCOMPAT
1329
        case TARGET_SO_BSDCOMPAT:
1330
                optname = SO_BSDCOMPAT;
1331
                break;
1332
#endif
1333
        case TARGET_SO_PASSCRED:
1334
                optname = SO_PASSCRED;
1335
                break;
1336
        case TARGET_SO_TIMESTAMP:
1337
                optname = SO_TIMESTAMP;
1338
                break;
1339
        case TARGET_SO_RCVLOWAT:
1340
                optname = SO_RCVLOWAT;
1341
                break;
1342
        case TARGET_SO_RCVTIMEO:
1343
                optname = SO_RCVTIMEO;
1344
                break;
1345
        case TARGET_SO_SNDTIMEO:
1346
                optname = SO_SNDTIMEO;
1347
                break;
1348
            break;
1349
        default:
1350
            goto unimplemented;
1351
        }
1352
        if (optlen < sizeof(uint32_t))
1353
            return -TARGET_EINVAL;
1354

    
1355
        if (get_user_u32(val, optval_addr))
1356
            return -TARGET_EFAULT;
1357
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1358
        break;
1359
    default:
1360
    unimplemented:
1361
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1362
        ret = -TARGET_ENOPROTOOPT;
1363
    }
1364
    return ret;
1365
}
1366

    
1367
/* do_getsockopt() Must return target values and target errnos. */
1368
static abi_long do_getsockopt(int sockfd, int level, int optname,
1369
                              abi_ulong optval_addr, abi_ulong optlen)
1370
{
1371
    abi_long ret;
1372
    int len, val;
1373
    socklen_t lv;
1374

    
1375
    switch(level) {
1376
    case TARGET_SOL_SOCKET:
1377
            level = SOL_SOCKET;
1378
        switch (optname) {
1379
        case TARGET_SO_LINGER:
1380
        case TARGET_SO_RCVTIMEO:
1381
        case TARGET_SO_SNDTIMEO:
1382
        case TARGET_SO_PEERCRED:
1383
        case TARGET_SO_PEERNAME:
1384
            /* These don't just return a single integer */
1385
            goto unimplemented;
1386
        default:
1387
            goto int_case;
1388
        }
1389
        break;
1390
    case SOL_TCP:
1391
        /* TCP options all take an 'int' value.  */
1392
    int_case:
1393
        if (get_user_u32(len, optlen))
1394
            return -TARGET_EFAULT;
1395
        if (len < 0)
1396
            return -TARGET_EINVAL;
1397
        lv = sizeof(int);
1398
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1399
        if (ret < 0)
1400
            return ret;
1401
        if (len > lv)
1402
            len = lv;
1403
        if (len == 4) {
1404
            if (put_user_u32(val, optval_addr))
1405
                return -TARGET_EFAULT;
1406
        } else {
1407
            if (put_user_u8(val, optval_addr))
1408
                return -TARGET_EFAULT;
1409
        }
1410
        if (put_user_u32(len, optlen))
1411
            return -TARGET_EFAULT;
1412
        break;
1413
    case SOL_IP:
1414
        switch(optname) {
1415
        case IP_TOS:
1416
        case IP_TTL:
1417
        case IP_HDRINCL:
1418
        case IP_ROUTER_ALERT:
1419
        case IP_RECVOPTS:
1420
        case IP_RETOPTS:
1421
        case IP_PKTINFO:
1422
        case IP_MTU_DISCOVER:
1423
        case IP_RECVERR:
1424
        case IP_RECVTOS:
1425
#ifdef IP_FREEBIND
1426
        case IP_FREEBIND:
1427
#endif
1428
        case IP_MULTICAST_TTL:
1429
        case IP_MULTICAST_LOOP:
1430
            if (get_user_u32(len, optlen))
1431
                return -TARGET_EFAULT;
1432
            if (len < 0)
1433
                return -TARGET_EINVAL;
1434
            lv = sizeof(int);
1435
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1436
            if (ret < 0)
1437
                return ret;
1438
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1439
                len = 1;
1440
                if (put_user_u32(len, optlen)
1441
                    || put_user_u8(val, optval_addr))
1442
                    return -TARGET_EFAULT;
1443
            } else {
1444
                if (len > sizeof(int))
1445
                    len = sizeof(int);
1446
                if (put_user_u32(len, optlen)
1447
                    || put_user_u32(val, optval_addr))
1448
                    return -TARGET_EFAULT;
1449
            }
1450
            break;
1451
        default:
1452
            ret = -TARGET_ENOPROTOOPT;
1453
            break;
1454
        }
1455
        break;
1456
    default:
1457
    unimplemented:
1458
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1459
                 level, optname);
1460
        ret = -TARGET_EOPNOTSUPP;
1461
        break;
1462
    }
1463
    return ret;
1464
}
1465

    
1466
/* FIXME
1467
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1468
 * other lock functions have a return code of 0 for failure.
1469
 */
1470
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1471
                           int count, int copy)
1472
{
1473
    struct target_iovec *target_vec;
1474
    abi_ulong base;
1475
    int i;
1476

    
1477
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1478
    if (!target_vec)
1479
        return -TARGET_EFAULT;
1480
    for(i = 0;i < count; i++) {
1481
        base = tswapl(target_vec[i].iov_base);
1482
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1483
        if (vec[i].iov_len != 0) {
1484
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1485
            /* Don't check lock_user return value. We must call writev even
1486
               if a element has invalid base address. */
1487
        } else {
1488
            /* zero length pointer is ignored */
1489
            vec[i].iov_base = NULL;
1490
        }
1491
    }
1492
    unlock_user (target_vec, target_addr, 0);
1493
    return 0;
1494
}
1495

    
1496
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1497
                             int count, int copy)
1498
{
1499
    struct target_iovec *target_vec;
1500
    abi_ulong base;
1501
    int i;
1502

    
1503
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1504
    if (!target_vec)
1505
        return -TARGET_EFAULT;
1506
    for(i = 0;i < count; i++) {
1507
        if (target_vec[i].iov_base) {
1508
            base = tswapl(target_vec[i].iov_base);
1509
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1510
        }
1511
    }
1512
    unlock_user (target_vec, target_addr, 0);
1513

    
1514
    return 0;
1515
}
1516

    
1517
/* do_socket() Must return target values and target errnos. */
1518
static abi_long do_socket(int domain, int type, int protocol)
1519
{
1520
#if defined(TARGET_MIPS)
1521
    switch(type) {
1522
    case TARGET_SOCK_DGRAM:
1523
        type = SOCK_DGRAM;
1524
        break;
1525
    case TARGET_SOCK_STREAM:
1526
        type = SOCK_STREAM;
1527
        break;
1528
    case TARGET_SOCK_RAW:
1529
        type = SOCK_RAW;
1530
        break;
1531
    case TARGET_SOCK_RDM:
1532
        type = SOCK_RDM;
1533
        break;
1534
    case TARGET_SOCK_SEQPACKET:
1535
        type = SOCK_SEQPACKET;
1536
        break;
1537
    case TARGET_SOCK_PACKET:
1538
        type = SOCK_PACKET;
1539
        break;
1540
    }
1541
#endif
1542
    if (domain == PF_NETLINK)
1543
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1544
    return get_errno(socket(domain, type, protocol));
1545
}
1546

    
1547
/* do_bind() Must return target values and target errnos. */
1548
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1549
                        socklen_t addrlen)
1550
{
1551
    void *addr;
1552
    abi_long ret;
1553

    
1554
    if (addrlen < 0)
1555
        return -TARGET_EINVAL;
1556

    
1557
    addr = alloca(addrlen+1);
1558

    
1559
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1560
    if (ret)
1561
        return ret;
1562

    
1563
    return get_errno(bind(sockfd, addr, addrlen));
1564
}
1565

    
1566
/* do_connect() Must return target values and target errnos. */
1567
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1568
                           socklen_t addrlen)
1569
{
1570
    void *addr;
1571
    abi_long ret;
1572

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

    
1576
    addr = alloca(addrlen);
1577

    
1578
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1579
    if (ret)
1580
        return ret;
1581

    
1582
    return get_errno(connect(sockfd, addr, addrlen));
1583
}
1584

    
1585
/* do_sendrecvmsg() Must return target values and target errnos. */
1586
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1587
                               int flags, int send)
1588
{
1589
    abi_long ret, len;
1590
    struct target_msghdr *msgp;
1591
    struct msghdr msg;
1592
    int count;
1593
    struct iovec *vec;
1594
    abi_ulong target_vec;
1595

    
1596
    /* FIXME */
1597
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1598
                          msgp,
1599
                          target_msg,
1600
                          send ? 1 : 0))
1601
        return -TARGET_EFAULT;
1602
    if (msgp->msg_name) {
1603
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1604
        msg.msg_name = alloca(msg.msg_namelen);
1605
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1606
                                msg.msg_namelen);
1607
        if (ret) {
1608
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1609
            return ret;
1610
        }
1611
    } else {
1612
        msg.msg_name = NULL;
1613
        msg.msg_namelen = 0;
1614
    }
1615
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1616
    msg.msg_control = alloca(msg.msg_controllen);
1617
    msg.msg_flags = tswap32(msgp->msg_flags);
1618

    
1619
    count = tswapl(msgp->msg_iovlen);
1620
    vec = alloca(count * sizeof(struct iovec));
1621
    target_vec = tswapl(msgp->msg_iov);
1622
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1623
    msg.msg_iovlen = count;
1624
    msg.msg_iov = vec;
1625

    
1626
    if (send) {
1627
        ret = target_to_host_cmsg(&msg, msgp);
1628
        if (ret == 0)
1629
            ret = get_errno(sendmsg(fd, &msg, flags));
1630
    } else {
1631
        ret = get_errno(recvmsg(fd, &msg, flags));
1632
        if (!is_error(ret)) {
1633
            len = ret;
1634
            ret = host_to_target_cmsg(msgp, &msg);
1635
            if (!is_error(ret))
1636
                ret = len;
1637
        }
1638
    }
1639
    unlock_iovec(vec, target_vec, count, !send);
1640
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1641
    return ret;
1642
}
1643

    
1644
/* do_accept() Must return target values and target errnos. */
1645
static abi_long do_accept(int fd, abi_ulong target_addr,
1646
                          abi_ulong target_addrlen_addr)
1647
{
1648
    socklen_t addrlen;
1649
    void *addr;
1650
    abi_long ret;
1651

    
1652
    if (target_addr == 0)
1653
       return get_errno(accept(fd, NULL, NULL));
1654

    
1655
    /* linux returns EINVAL if addrlen pointer is invalid */
1656
    if (get_user_u32(addrlen, target_addrlen_addr))
1657
        return -TARGET_EINVAL;
1658

    
1659
    if (addrlen < 0)
1660
        return -TARGET_EINVAL;
1661

    
1662
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1663
        return -TARGET_EINVAL;
1664

    
1665
    addr = alloca(addrlen);
1666

    
1667
    ret = get_errno(accept(fd, addr, &addrlen));
1668
    if (!is_error(ret)) {
1669
        host_to_target_sockaddr(target_addr, addr, addrlen);
1670
        if (put_user_u32(addrlen, target_addrlen_addr))
1671
            ret = -TARGET_EFAULT;
1672
    }
1673
    return ret;
1674
}
1675

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

    
1684
    if (get_user_u32(addrlen, target_addrlen_addr))
1685
        return -TARGET_EFAULT;
1686

    
1687
    if (addrlen < 0)
1688
        return -TARGET_EINVAL;
1689

    
1690
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1691
        return -TARGET_EFAULT;
1692

    
1693
    addr = alloca(addrlen);
1694

    
1695
    ret = get_errno(getpeername(fd, addr, &addrlen));
1696
    if (!is_error(ret)) {
1697
        host_to_target_sockaddr(target_addr, addr, addrlen);
1698
        if (put_user_u32(addrlen, target_addrlen_addr))
1699
            ret = -TARGET_EFAULT;
1700
    }
1701
    return ret;
1702
}
1703

    
1704
/* do_getsockname() Must return target values and target errnos. */
1705
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1706
                               abi_ulong target_addrlen_addr)
1707
{
1708
    socklen_t addrlen;
1709
    void *addr;
1710
    abi_long ret;
1711

    
1712
    if (get_user_u32(addrlen, target_addrlen_addr))
1713
        return -TARGET_EFAULT;
1714

    
1715
    if (addrlen < 0)
1716
        return -TARGET_EINVAL;
1717

    
1718
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1719
        return -TARGET_EFAULT;
1720

    
1721
    addr = alloca(addrlen);
1722

    
1723
    ret = get_errno(getsockname(fd, addr, &addrlen));
1724
    if (!is_error(ret)) {
1725
        host_to_target_sockaddr(target_addr, addr, addrlen);
1726
        if (put_user_u32(addrlen, target_addrlen_addr))
1727
            ret = -TARGET_EFAULT;
1728
    }
1729
    return ret;
1730
}
1731

    
1732
/* do_socketpair() Must return target values and target errnos. */
1733
static abi_long do_socketpair(int domain, int type, int protocol,
1734
                              abi_ulong target_tab_addr)
1735
{
1736
    int tab[2];
1737
    abi_long ret;
1738

    
1739
    ret = get_errno(socketpair(domain, type, protocol, tab));
1740
    if (!is_error(ret)) {
1741
        if (put_user_s32(tab[0], target_tab_addr)
1742
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1743
            ret = -TARGET_EFAULT;
1744
    }
1745
    return ret;
1746
}
1747

    
1748
/* do_sendto() Must return target values and target errnos. */
1749
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1750
                          abi_ulong target_addr, socklen_t addrlen)
1751
{
1752
    void *addr;
1753
    void *host_msg;
1754
    abi_long ret;
1755

    
1756
    if (addrlen < 0)
1757
        return -TARGET_EINVAL;
1758

    
1759
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1760
    if (!host_msg)
1761
        return -TARGET_EFAULT;
1762
    if (target_addr) {
1763
        addr = alloca(addrlen);
1764
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1765
        if (ret) {
1766
            unlock_user(host_msg, msg, 0);
1767
            return ret;
1768
        }
1769
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1770
    } else {
1771
        ret = get_errno(send(fd, host_msg, len, flags));
1772
    }
1773
    unlock_user(host_msg, msg, 0);
1774
    return ret;
1775
}
1776

    
1777
/* do_recvfrom() Must return target values and target errnos. */
1778
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1779
                            abi_ulong target_addr,
1780
                            abi_ulong target_addrlen)
1781
{
1782
    socklen_t addrlen;
1783
    void *addr;
1784
    void *host_msg;
1785
    abi_long ret;
1786

    
1787
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1788
    if (!host_msg)
1789
        return -TARGET_EFAULT;
1790
    if (target_addr) {
1791
        if (get_user_u32(addrlen, target_addrlen)) {
1792
            ret = -TARGET_EFAULT;
1793
            goto fail;
1794
        }
1795
        if (addrlen < 0) {
1796
            ret = -TARGET_EINVAL;
1797
            goto fail;
1798
        }
1799
        addr = alloca(addrlen);
1800
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1801
    } else {
1802
        addr = NULL; /* To keep compiler quiet.  */
1803
        ret = get_errno(recv(fd, host_msg, len, flags));
1804
    }
1805
    if (!is_error(ret)) {
1806
        if (target_addr) {
1807
            host_to_target_sockaddr(target_addr, addr, addrlen);
1808
            if (put_user_u32(addrlen, target_addrlen)) {
1809
                ret = -TARGET_EFAULT;
1810
                goto fail;
1811
            }
1812
        }
1813
        unlock_user(host_msg, msg, len);
1814
    } else {
1815
fail:
1816
        unlock_user(host_msg, msg, 0);
1817
    }
1818
    return ret;
1819
}
1820

    
1821
#ifdef TARGET_NR_socketcall
1822
/* do_socketcall() Must return target values and target errnos. */
1823
static abi_long do_socketcall(int num, abi_ulong vptr)
1824
{
1825
    abi_long ret;
1826
    const int n = sizeof(abi_ulong);
1827

    
1828
    switch(num) {
1829
    case SOCKOP_socket:
1830
        {
1831
            abi_ulong domain, type, protocol;
1832

    
1833
            if (get_user_ual(domain, vptr)
1834
                || get_user_ual(type, vptr + n)
1835
                || get_user_ual(protocol, vptr + 2 * n))
1836
                return -TARGET_EFAULT;
1837

    
1838
            ret = do_socket(domain, type, protocol);
1839
        }
1840
        break;
1841
    case SOCKOP_bind:
1842
        {
1843
            abi_ulong sockfd;
1844
            abi_ulong target_addr;
1845
            socklen_t addrlen;
1846

    
1847
            if (get_user_ual(sockfd, vptr)
1848
                || get_user_ual(target_addr, vptr + n)
1849
                || get_user_ual(addrlen, vptr + 2 * n))
1850
                return -TARGET_EFAULT;
1851

    
1852
            ret = do_bind(sockfd, target_addr, addrlen);
1853
        }
1854
        break;
1855
    case SOCKOP_connect:
1856
        {
1857
            abi_ulong sockfd;
1858
            abi_ulong target_addr;
1859
            socklen_t addrlen;
1860

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

    
1866
            ret = do_connect(sockfd, target_addr, addrlen);
1867
        }
1868
        break;
1869
    case SOCKOP_listen:
1870
        {
1871
            abi_ulong sockfd, backlog;
1872

    
1873
            if (get_user_ual(sockfd, vptr)
1874
                || get_user_ual(backlog, vptr + n))
1875
                return -TARGET_EFAULT;
1876

    
1877
            ret = get_errno(listen(sockfd, backlog));
1878
        }
1879
        break;
1880
    case SOCKOP_accept:
1881
        {
1882
            abi_ulong sockfd;
1883
            abi_ulong target_addr, target_addrlen;
1884

    
1885
            if (get_user_ual(sockfd, vptr)
1886
                || get_user_ual(target_addr, vptr + n)
1887
                || get_user_ual(target_addrlen, vptr + 2 * n))
1888
                return -TARGET_EFAULT;
1889

    
1890
            ret = do_accept(sockfd, target_addr, target_addrlen);
1891
        }
1892
        break;
1893
    case SOCKOP_getsockname:
1894
        {
1895
            abi_ulong sockfd;
1896
            abi_ulong target_addr, target_addrlen;
1897

    
1898
            if (get_user_ual(sockfd, vptr)
1899
                || get_user_ual(target_addr, vptr + n)
1900
                || get_user_ual(target_addrlen, vptr + 2 * n))
1901
                return -TARGET_EFAULT;
1902

    
1903
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1904
        }
1905
        break;
1906
    case SOCKOP_getpeername:
1907
        {
1908
            abi_ulong sockfd;
1909
            abi_ulong target_addr, target_addrlen;
1910

    
1911
            if (get_user_ual(sockfd, vptr)
1912
                || get_user_ual(target_addr, vptr + n)
1913
                || get_user_ual(target_addrlen, vptr + 2 * n))
1914
                return -TARGET_EFAULT;
1915

    
1916
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1917
        }
1918
        break;
1919
    case SOCKOP_socketpair:
1920
        {
1921
            abi_ulong domain, type, protocol;
1922
            abi_ulong tab;
1923

    
1924
            if (get_user_ual(domain, vptr)
1925
                || get_user_ual(type, vptr + n)
1926
                || get_user_ual(protocol, vptr + 2 * n)
1927
                || get_user_ual(tab, vptr + 3 * n))
1928
                return -TARGET_EFAULT;
1929

    
1930
            ret = do_socketpair(domain, type, protocol, tab);
1931
        }
1932
        break;
1933
    case SOCKOP_send:
1934
        {
1935
            abi_ulong sockfd;
1936
            abi_ulong msg;
1937
            size_t len;
1938
            abi_ulong flags;
1939

    
1940
            if (get_user_ual(sockfd, vptr)
1941
                || get_user_ual(msg, vptr + n)
1942
                || get_user_ual(len, vptr + 2 * n)
1943
                || get_user_ual(flags, vptr + 3 * n))
1944
                return -TARGET_EFAULT;
1945

    
1946
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1947
        }
1948
        break;
1949
    case SOCKOP_recv:
1950
        {
1951
            abi_ulong sockfd;
1952
            abi_ulong msg;
1953
            size_t len;
1954
            abi_ulong flags;
1955

    
1956
            if (get_user_ual(sockfd, vptr)
1957
                || get_user_ual(msg, vptr + n)
1958
                || get_user_ual(len, vptr + 2 * n)
1959
                || get_user_ual(flags, vptr + 3 * n))
1960
                return -TARGET_EFAULT;
1961

    
1962
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1963
        }
1964
        break;
1965
    case SOCKOP_sendto:
1966
        {
1967
            abi_ulong sockfd;
1968
            abi_ulong msg;
1969
            size_t len;
1970
            abi_ulong flags;
1971
            abi_ulong addr;
1972
            socklen_t addrlen;
1973

    
1974
            if (get_user_ual(sockfd, vptr)
1975
                || get_user_ual(msg, vptr + n)
1976
                || get_user_ual(len, vptr + 2 * n)
1977
                || get_user_ual(flags, vptr + 3 * n)
1978
                || get_user_ual(addr, vptr + 4 * n)
1979
                || get_user_ual(addrlen, vptr + 5 * n))
1980
                return -TARGET_EFAULT;
1981

    
1982
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1983
        }
1984
        break;
1985
    case SOCKOP_recvfrom:
1986
        {
1987
            abi_ulong sockfd;
1988
            abi_ulong msg;
1989
            size_t len;
1990
            abi_ulong flags;
1991
            abi_ulong addr;
1992
            socklen_t addrlen;
1993

    
1994
            if (get_user_ual(sockfd, vptr)
1995
                || get_user_ual(msg, vptr + n)
1996
                || get_user_ual(len, vptr + 2 * n)
1997
                || get_user_ual(flags, vptr + 3 * n)
1998
                || get_user_ual(addr, vptr + 4 * n)
1999
                || get_user_ual(addrlen, vptr + 5 * n))
2000
                return -TARGET_EFAULT;
2001

    
2002
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2003
        }
2004
        break;
2005
    case SOCKOP_shutdown:
2006
        {
2007
            abi_ulong sockfd, how;
2008

    
2009
            if (get_user_ual(sockfd, vptr)
2010
                || get_user_ual(how, vptr + n))
2011
                return -TARGET_EFAULT;
2012

    
2013
            ret = get_errno(shutdown(sockfd, how));
2014
        }
2015
        break;
2016
    case SOCKOP_sendmsg:
2017
    case SOCKOP_recvmsg:
2018
        {
2019
            abi_ulong fd;
2020
            abi_ulong target_msg;
2021
            abi_ulong flags;
2022

    
2023
            if (get_user_ual(fd, vptr)
2024
                || get_user_ual(target_msg, vptr + n)
2025
                || get_user_ual(flags, vptr + 2 * n))
2026
                return -TARGET_EFAULT;
2027

    
2028
            ret = do_sendrecvmsg(fd, target_msg, flags,
2029
                                 (num == SOCKOP_sendmsg));
2030
        }
2031
        break;
2032
    case SOCKOP_setsockopt:
2033
        {
2034
            abi_ulong sockfd;
2035
            abi_ulong level;
2036
            abi_ulong optname;
2037
            abi_ulong optval;
2038
            socklen_t optlen;
2039

    
2040
            if (get_user_ual(sockfd, vptr)
2041
                || get_user_ual(level, vptr + n)
2042
                || get_user_ual(optname, vptr + 2 * n)
2043
                || get_user_ual(optval, vptr + 3 * n)
2044
                || get_user_ual(optlen, vptr + 4 * n))
2045
                return -TARGET_EFAULT;
2046

    
2047
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2048
        }
2049
        break;
2050
    case SOCKOP_getsockopt:
2051
        {
2052
            abi_ulong sockfd;
2053
            abi_ulong level;
2054
            abi_ulong optname;
2055
            abi_ulong optval;
2056
            socklen_t optlen;
2057

    
2058
            if (get_user_ual(sockfd, vptr)
2059
                || get_user_ual(level, vptr + n)
2060
                || get_user_ual(optname, vptr + 2 * n)
2061
                || get_user_ual(optval, vptr + 3 * n)
2062
                || get_user_ual(optlen, vptr + 4 * n))
2063
                return -TARGET_EFAULT;
2064

    
2065
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2066
        }
2067
        break;
2068
    default:
2069
        gemu_log("Unsupported socketcall: %d\n", num);
2070
        ret = -TARGET_ENOSYS;
2071
        break;
2072
    }
2073
    return ret;
2074
}
2075
#endif
2076

    
2077
#define N_SHM_REGIONS        32
2078

    
2079
static struct shm_region {
2080
    abi_ulong        start;
2081
    abi_ulong        size;
2082
} shm_regions[N_SHM_REGIONS];
2083

    
2084
struct target_ipc_perm
2085
{
2086
    abi_long __key;
2087
    abi_ulong uid;
2088
    abi_ulong gid;
2089
    abi_ulong cuid;
2090
    abi_ulong cgid;
2091
    unsigned short int mode;
2092
    unsigned short int __pad1;
2093
    unsigned short int __seq;
2094
    unsigned short int __pad2;
2095
    abi_ulong __unused1;
2096
    abi_ulong __unused2;
2097
};
2098

    
2099
struct target_semid_ds
2100
{
2101
  struct target_ipc_perm sem_perm;
2102
  abi_ulong sem_otime;
2103
  abi_ulong __unused1;
2104
  abi_ulong sem_ctime;
2105
  abi_ulong __unused2;
2106
  abi_ulong sem_nsems;
2107
  abi_ulong __unused3;
2108
  abi_ulong __unused4;
2109
};
2110

    
2111
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2112
                                               abi_ulong target_addr)
2113
{
2114
    struct target_ipc_perm *target_ip;
2115
    struct target_semid_ds *target_sd;
2116

    
2117
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2118
        return -TARGET_EFAULT;
2119
    target_ip = &(target_sd->sem_perm);
2120
    host_ip->__key = tswapl(target_ip->__key);
2121
    host_ip->uid = tswapl(target_ip->uid);
2122
    host_ip->gid = tswapl(target_ip->gid);
2123
    host_ip->cuid = tswapl(target_ip->cuid);
2124
    host_ip->cgid = tswapl(target_ip->cgid);
2125
    host_ip->mode = tswapl(target_ip->mode);
2126
    unlock_user_struct(target_sd, target_addr, 0);
2127
    return 0;
2128
}
2129

    
2130
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2131
                                               struct ipc_perm *host_ip)
2132
{
2133
    struct target_ipc_perm *target_ip;
2134
    struct target_semid_ds *target_sd;
2135

    
2136
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2137
        return -TARGET_EFAULT;
2138
    target_ip = &(target_sd->sem_perm);
2139
    target_ip->__key = tswapl(host_ip->__key);
2140
    target_ip->uid = tswapl(host_ip->uid);
2141
    target_ip->gid = tswapl(host_ip->gid);
2142
    target_ip->cuid = tswapl(host_ip->cuid);
2143
    target_ip->cgid = tswapl(host_ip->cgid);
2144
    target_ip->mode = tswapl(host_ip->mode);
2145
    unlock_user_struct(target_sd, target_addr, 1);
2146
    return 0;
2147
}
2148

    
2149
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2150
                                               abi_ulong target_addr)
2151
{
2152
    struct target_semid_ds *target_sd;
2153

    
2154
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2155
        return -TARGET_EFAULT;
2156
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2157
        return -TARGET_EFAULT;
2158
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2159
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2160
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2161
    unlock_user_struct(target_sd, target_addr, 0);
2162
    return 0;
2163
}
2164

    
2165
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2166
                                               struct semid_ds *host_sd)
2167
{
2168
    struct target_semid_ds *target_sd;
2169

    
2170
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2171
        return -TARGET_EFAULT;
2172
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2173
        return -TARGET_EFAULT;;
2174
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2175
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2176
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2177
    unlock_user_struct(target_sd, target_addr, 1);
2178
    return 0;
2179
}
2180

    
2181
struct target_seminfo {
2182
    int semmap;
2183
    int semmni;
2184
    int semmns;
2185
    int semmnu;
2186
    int semmsl;
2187
    int semopm;
2188
    int semume;
2189
    int semusz;
2190
    int semvmx;
2191
    int semaem;
2192
};
2193

    
2194
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2195
                                              struct seminfo *host_seminfo)
2196
{
2197
    struct target_seminfo *target_seminfo;
2198
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2199
        return -TARGET_EFAULT;
2200
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2201
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2202
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2203
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2204
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2205
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2206
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2207
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2208
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2209
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2210
    unlock_user_struct(target_seminfo, target_addr, 1);
2211
    return 0;
2212
}
2213

    
2214
union semun {
2215
        int val;
2216
        struct semid_ds *buf;
2217
        unsigned short *array;
2218
        struct seminfo *__buf;
2219
};
2220

    
2221
union target_semun {
2222
        int val;
2223
        abi_ulong buf;
2224
        abi_ulong array;
2225
        abi_ulong __buf;
2226
};
2227

    
2228
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2229
                                               abi_ulong target_addr)
2230
{
2231
    int nsems;
2232
    unsigned short *array;
2233
    union semun semun;
2234
    struct semid_ds semid_ds;
2235
    int i, ret;
2236

    
2237
    semun.buf = &semid_ds;
2238

    
2239
    ret = semctl(semid, 0, IPC_STAT, semun);
2240
    if (ret == -1)
2241
        return get_errno(ret);
2242

    
2243
    nsems = semid_ds.sem_nsems;
2244

    
2245
    *host_array = malloc(nsems*sizeof(unsigned short));
2246
    array = lock_user(VERIFY_READ, target_addr,
2247
                      nsems*sizeof(unsigned short), 1);
2248
    if (!array)
2249
        return -TARGET_EFAULT;
2250

    
2251
    for(i=0; i<nsems; i++) {
2252
        __get_user((*host_array)[i], &array[i]);
2253
    }
2254
    unlock_user(array, target_addr, 0);
2255

    
2256
    return 0;
2257
}
2258

    
2259
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2260
                                               unsigned short **host_array)
2261
{
2262
    int nsems;
2263
    unsigned short *array;
2264
    union semun semun;
2265
    struct semid_ds semid_ds;
2266
    int i, ret;
2267

    
2268
    semun.buf = &semid_ds;
2269

    
2270
    ret = semctl(semid, 0, IPC_STAT, semun);
2271
    if (ret == -1)
2272
        return get_errno(ret);
2273

    
2274
    nsems = semid_ds.sem_nsems;
2275

    
2276
    array = lock_user(VERIFY_WRITE, target_addr,
2277
                      nsems*sizeof(unsigned short), 0);
2278
    if (!array)
2279
        return -TARGET_EFAULT;
2280

    
2281
    for(i=0; i<nsems; i++) {
2282
        __put_user((*host_array)[i], &array[i]);
2283
    }
2284
    free(*host_array);
2285
    unlock_user(array, target_addr, 1);
2286

    
2287
    return 0;
2288
}
2289

    
2290
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2291
                                 union target_semun target_su)
2292
{
2293
    union semun arg;
2294
    struct semid_ds dsarg;
2295
    unsigned short *array = NULL;
2296
    struct seminfo seminfo;
2297
    abi_long ret = -TARGET_EINVAL;
2298
    abi_long err;
2299
    cmd &= 0xff;
2300

    
2301
    switch( cmd ) {
2302
        case GETVAL:
2303
        case SETVAL:
2304
            arg.val = tswapl(target_su.val);
2305
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2306
            target_su.val = tswapl(arg.val);
2307
            break;
2308
        case GETALL:
2309
        case SETALL:
2310
            err = target_to_host_semarray(semid, &array, target_su.array);
2311
            if (err)
2312
                return err;
2313
            arg.array = array;
2314
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2315
            err = host_to_target_semarray(semid, target_su.array, &array);
2316
            if (err)
2317
                return err;
2318
            break;
2319
        case IPC_STAT:
2320
        case IPC_SET:
2321
        case SEM_STAT:
2322
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2323
            if (err)
2324
                return err;
2325
            arg.buf = &dsarg;
2326
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2327
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2328
            if (err)
2329
                return err;
2330
            break;
2331
        case IPC_INFO:
2332
        case SEM_INFO:
2333
            arg.__buf = &seminfo;
2334
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2335
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2336
            if (err)
2337
                return err;
2338
            break;
2339
        case IPC_RMID:
2340
        case GETPID:
2341
        case GETNCNT:
2342
        case GETZCNT:
2343
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2344
            break;
2345
    }
2346

    
2347
    return ret;
2348
}
2349

    
2350
struct target_sembuf {
2351
    unsigned short sem_num;
2352
    short sem_op;
2353
    short sem_flg;
2354
};
2355

    
2356
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2357
                                             abi_ulong target_addr,
2358
                                             unsigned nsops)
2359
{
2360
    struct target_sembuf *target_sembuf;
2361
    int i;
2362

    
2363
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2364
                              nsops*sizeof(struct target_sembuf), 1);
2365
    if (!target_sembuf)
2366
        return -TARGET_EFAULT;
2367

    
2368
    for(i=0; i<nsops; i++) {
2369
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2370
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2371
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2372
    }
2373

    
2374
    unlock_user(target_sembuf, target_addr, 0);
2375

    
2376
    return 0;
2377
}
2378

    
2379
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2380
{
2381
    struct sembuf sops[nsops];
2382

    
2383
    if (target_to_host_sembuf(sops, ptr, nsops))
2384
        return -TARGET_EFAULT;
2385

    
2386
    return semop(semid, sops, nsops);
2387
}
2388

    
2389
struct target_msqid_ds
2390
{
2391
    struct target_ipc_perm msg_perm;
2392
    abi_ulong msg_stime;
2393
#if TARGET_ABI_BITS == 32
2394
    abi_ulong __unused1;
2395
#endif
2396
    abi_ulong msg_rtime;
2397
#if TARGET_ABI_BITS == 32
2398
    abi_ulong __unused2;
2399
#endif
2400
    abi_ulong msg_ctime;
2401
#if TARGET_ABI_BITS == 32
2402
    abi_ulong __unused3;
2403
#endif
2404
    abi_ulong __msg_cbytes;
2405
    abi_ulong msg_qnum;
2406
    abi_ulong msg_qbytes;
2407
    abi_ulong msg_lspid;
2408
    abi_ulong msg_lrpid;
2409
    abi_ulong __unused4;
2410
    abi_ulong __unused5;
2411
};
2412

    
2413
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2414
                                               abi_ulong target_addr)
2415
{
2416
    struct target_msqid_ds *target_md;
2417

    
2418
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2419
        return -TARGET_EFAULT;
2420
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2421
        return -TARGET_EFAULT;
2422
    host_md->msg_stime = tswapl(target_md->msg_stime);
2423
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2424
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2425
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2426
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2427
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2428
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2429
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2430
    unlock_user_struct(target_md, target_addr, 0);
2431
    return 0;
2432
}
2433

    
2434
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2435
                                               struct msqid_ds *host_md)
2436
{
2437
    struct target_msqid_ds *target_md;
2438

    
2439
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2440
        return -TARGET_EFAULT;
2441
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2442
        return -TARGET_EFAULT;
2443
    target_md->msg_stime = tswapl(host_md->msg_stime);
2444
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2445
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2446
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2447
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2448
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2449
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2450
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2451
    unlock_user_struct(target_md, target_addr, 1);
2452
    return 0;
2453
}
2454

    
2455
struct target_msginfo {
2456
    int msgpool;
2457
    int msgmap;
2458
    int msgmax;
2459
    int msgmnb;
2460
    int msgmni;
2461
    int msgssz;
2462
    int msgtql;
2463
    unsigned short int msgseg;
2464
};
2465

    
2466
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2467
                                              struct msginfo *host_msginfo)
2468
{
2469
    struct target_msginfo *target_msginfo;
2470
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2471
        return -TARGET_EFAULT;
2472
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2473
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2474
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2475
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2476
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2477
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2478
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2479
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2480
    unlock_user_struct(target_msginfo, target_addr, 1);
2481
    return 0;
2482
}
2483

    
2484
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2485
{
2486
    struct msqid_ds dsarg;
2487
    struct msginfo msginfo;
2488
    abi_long ret = -TARGET_EINVAL;
2489

    
2490
    cmd &= 0xff;
2491

    
2492
    switch (cmd) {
2493
    case IPC_STAT:
2494
    case IPC_SET:
2495
    case MSG_STAT:
2496
        if (target_to_host_msqid_ds(&dsarg,ptr))
2497
            return -TARGET_EFAULT;
2498
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2499
        if (host_to_target_msqid_ds(ptr,&dsarg))
2500
            return -TARGET_EFAULT;
2501
        break;
2502
    case IPC_RMID:
2503
        ret = get_errno(msgctl(msgid, cmd, NULL));
2504
        break;
2505
    case IPC_INFO:
2506
    case MSG_INFO:
2507
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2508
        if (host_to_target_msginfo(ptr, &msginfo))
2509
            return -TARGET_EFAULT;
2510
        break;
2511
    }
2512

    
2513
    return ret;
2514
}
2515

    
2516
struct target_msgbuf {
2517
    abi_long mtype;
2518
    char        mtext[1];
2519
};
2520

    
2521
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2522
                                 unsigned int msgsz, int msgflg)
2523
{
2524
    struct target_msgbuf *target_mb;
2525
    struct msgbuf *host_mb;
2526
    abi_long ret = 0;
2527

    
2528
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2529
        return -TARGET_EFAULT;
2530
    host_mb = malloc(msgsz+sizeof(long));
2531
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2532
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2533
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2534
    free(host_mb);
2535
    unlock_user_struct(target_mb, msgp, 0);
2536

    
2537
    return ret;
2538
}
2539

    
2540
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2541
                                 unsigned int msgsz, abi_long msgtyp,
2542
                                 int msgflg)
2543
{
2544
    struct target_msgbuf *target_mb;
2545
    char *target_mtext;
2546
    struct msgbuf *host_mb;
2547
    abi_long ret = 0;
2548

    
2549
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2550
        return -TARGET_EFAULT;
2551

    
2552
    host_mb = malloc(msgsz+sizeof(long));
2553
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2554

    
2555
    if (ret > 0) {
2556
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2557
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2558
        if (!target_mtext) {
2559
            ret = -TARGET_EFAULT;
2560
            goto end;
2561
        }
2562
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2563
        unlock_user(target_mtext, target_mtext_addr, ret);
2564
    }
2565

    
2566
    target_mb->mtype = tswapl(host_mb->mtype);
2567
    free(host_mb);
2568

    
2569
end:
2570
    if (target_mb)
2571
        unlock_user_struct(target_mb, msgp, 1);
2572
    return ret;
2573
}
2574

    
2575
struct target_shmid_ds
2576
{
2577
    struct target_ipc_perm shm_perm;
2578
    abi_ulong shm_segsz;
2579
    abi_ulong shm_atime;
2580
#if TARGET_ABI_BITS == 32
2581
    abi_ulong __unused1;
2582
#endif
2583
    abi_ulong shm_dtime;
2584
#if TARGET_ABI_BITS == 32
2585
    abi_ulong __unused2;
2586
#endif
2587
    abi_ulong shm_ctime;
2588
#if TARGET_ABI_BITS == 32
2589
    abi_ulong __unused3;
2590
#endif
2591
    int shm_cpid;
2592
    int shm_lpid;
2593
    abi_ulong shm_nattch;
2594
    unsigned long int __unused4;
2595
    unsigned long int __unused5;
2596
};
2597

    
2598
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2599
                                               abi_ulong target_addr)
2600
{
2601
    struct target_shmid_ds *target_sd;
2602

    
2603
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2604
        return -TARGET_EFAULT;
2605
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2606
        return -TARGET_EFAULT;
2607
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2608
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2609
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2610
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2611
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2612
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2613
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2614
    unlock_user_struct(target_sd, target_addr, 0);
2615
    return 0;
2616
}
2617

    
2618
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2619
                                               struct shmid_ds *host_sd)
2620
{
2621
    struct target_shmid_ds *target_sd;
2622

    
2623
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2624
        return -TARGET_EFAULT;
2625
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2626
        return -TARGET_EFAULT;
2627
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2628
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2629
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2630
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2631
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2632
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2633
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2634
    unlock_user_struct(target_sd, target_addr, 1);
2635
    return 0;
2636
}
2637

    
2638
struct  target_shminfo {
2639
    abi_ulong shmmax;
2640
    abi_ulong shmmin;
2641
    abi_ulong shmmni;
2642
    abi_ulong shmseg;
2643
    abi_ulong shmall;
2644
};
2645

    
2646
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2647
                                              struct shminfo *host_shminfo)
2648
{
2649
    struct target_shminfo *target_shminfo;
2650
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2651
        return -TARGET_EFAULT;
2652
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2653
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2654
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2655
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2656
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2657
    unlock_user_struct(target_shminfo, target_addr, 1);
2658
    return 0;
2659
}
2660

    
2661
struct target_shm_info {
2662
    int used_ids;
2663
    abi_ulong shm_tot;
2664
    abi_ulong shm_rss;
2665
    abi_ulong shm_swp;
2666
    abi_ulong swap_attempts;
2667
    abi_ulong swap_successes;
2668
};
2669

    
2670
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2671
                                               struct shm_info *host_shm_info)
2672
{
2673
    struct target_shm_info *target_shm_info;
2674
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2675
        return -TARGET_EFAULT;
2676
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2677
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2678
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2679
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2680
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2681
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2682
    unlock_user_struct(target_shm_info, target_addr, 1);
2683
    return 0;
2684
}
2685

    
2686
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2687
{
2688
    struct shmid_ds dsarg;
2689
    struct shminfo shminfo;
2690
    struct shm_info shm_info;
2691
    abi_long ret = -TARGET_EINVAL;
2692

    
2693
    cmd &= 0xff;
2694

    
2695
    switch(cmd) {
2696
    case IPC_STAT:
2697
    case IPC_SET:
2698
    case SHM_STAT:
2699
        if (target_to_host_shmid_ds(&dsarg, buf))
2700
            return -TARGET_EFAULT;
2701
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2702
        if (host_to_target_shmid_ds(buf, &dsarg))
2703
            return -TARGET_EFAULT;
2704
        break;
2705
    case IPC_INFO:
2706
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2707
        if (host_to_target_shminfo(buf, &shminfo))
2708
            return -TARGET_EFAULT;
2709
        break;
2710
    case SHM_INFO:
2711
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2712
        if (host_to_target_shm_info(buf, &shm_info))
2713
            return -TARGET_EFAULT;
2714
        break;
2715
    case IPC_RMID:
2716
    case SHM_LOCK:
2717
    case SHM_UNLOCK:
2718
        ret = get_errno(shmctl(shmid, cmd, NULL));
2719
        break;
2720
    }
2721

    
2722
    return ret;
2723
}
2724

    
2725
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2726
{
2727
    abi_long raddr;
2728
    void *host_raddr;
2729
    struct shmid_ds shm_info;
2730
    int i,ret;
2731

    
2732
    /* find out the length of the shared memory segment */
2733
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2734
    if (is_error(ret)) {
2735
        /* can't get length, bail out */
2736
        return ret;
2737
    }
2738

    
2739
    mmap_lock();
2740

    
2741
    if (shmaddr)
2742
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2743
    else {
2744
        abi_ulong mmap_start;
2745

    
2746
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2747

    
2748
        if (mmap_start == -1) {
2749
            errno = ENOMEM;
2750
            host_raddr = (void *)-1;
2751
        } else
2752
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2753
    }
2754

    
2755
    if (host_raddr == (void *)-1) {
2756
        mmap_unlock();
2757
        return get_errno((long)host_raddr);
2758
    }
2759
    raddr=h2g((unsigned long)host_raddr);
2760

    
2761
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2762
                   PAGE_VALID | PAGE_READ |
2763
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2764

    
2765
    for (i = 0; i < N_SHM_REGIONS; i++) {
2766
        if (shm_regions[i].start == 0) {
2767
            shm_regions[i].start = raddr;
2768
            shm_regions[i].size = shm_info.shm_segsz;
2769
            break;
2770
        }
2771
    }
2772

    
2773
    mmap_unlock();
2774
    return raddr;
2775

    
2776
}
2777

    
2778
static inline abi_long do_shmdt(abi_ulong shmaddr)
2779
{
2780
    int i;
2781

    
2782
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2783
        if (shm_regions[i].start == shmaddr) {
2784
            shm_regions[i].start = 0;
2785
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
2786
            break;
2787
        }
2788
    }
2789

    
2790
    return get_errno(shmdt(g2h(shmaddr)));
2791
}
2792

    
2793
#ifdef TARGET_NR_ipc
2794
/* ??? This only works with linear mappings.  */
2795
/* do_ipc() must return target values and target errnos. */
2796
static abi_long do_ipc(unsigned int call, int first,
2797
                       int second, int third,
2798
                       abi_long ptr, abi_long fifth)
2799
{
2800
    int version;
2801
    abi_long ret = 0;
2802

    
2803
    version = call >> 16;
2804
    call &= 0xffff;
2805

    
2806
    switch (call) {
2807
    case IPCOP_semop:
2808
        ret = do_semop(first, ptr, second);
2809
        break;
2810

    
2811
    case IPCOP_semget:
2812
        ret = get_errno(semget(first, second, third));
2813
        break;
2814

    
2815
    case IPCOP_semctl:
2816
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2817
        break;
2818

    
2819
    case IPCOP_msgget:
2820
        ret = get_errno(msgget(first, second));
2821
        break;
2822

    
2823
    case IPCOP_msgsnd:
2824
        ret = do_msgsnd(first, ptr, second, third);
2825
        break;
2826

    
2827
    case IPCOP_msgctl:
2828
        ret = do_msgctl(first, second, ptr);
2829
        break;
2830

    
2831
    case IPCOP_msgrcv:
2832
        switch (version) {
2833
        case 0:
2834
            {
2835
                struct target_ipc_kludge {
2836
                    abi_long msgp;
2837
                    abi_long msgtyp;
2838
                } *tmp;
2839

    
2840
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2841
                    ret = -TARGET_EFAULT;
2842
                    break;
2843
                }
2844

    
2845
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2846

    
2847
                unlock_user_struct(tmp, ptr, 0);
2848
                break;
2849
            }
2850
        default:
2851
            ret = do_msgrcv(first, ptr, second, fifth, third);
2852
        }
2853
        break;
2854

    
2855
    case IPCOP_shmat:
2856
        switch (version) {
2857
        default:
2858
        {
2859
            abi_ulong raddr;
2860
            raddr = do_shmat(first, ptr, second);
2861
            if (is_error(raddr))
2862
                return get_errno(raddr);
2863
            if (put_user_ual(raddr, third))
2864
                return -TARGET_EFAULT;
2865
            break;
2866
        }
2867
        case 1:
2868
            ret = -TARGET_EINVAL;
2869
            break;
2870
        }
2871
        break;
2872
    case IPCOP_shmdt:
2873
        ret = do_shmdt(ptr);
2874
        break;
2875

    
2876
    case IPCOP_shmget:
2877
        /* IPC_* flag values are the same on all linux platforms */
2878
        ret = get_errno(shmget(first, second, third));
2879
        break;
2880

    
2881
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2882
    case IPCOP_shmctl:
2883
        ret = do_shmctl(first, second, third);
2884
        break;
2885
    default:
2886
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2887
        ret = -TARGET_ENOSYS;
2888
        break;
2889
    }
2890
    return ret;
2891
}
2892
#endif
2893

    
2894
/* kernel structure types definitions */
2895
#define IFNAMSIZ        16
2896

    
2897
#define STRUCT(name, ...) STRUCT_ ## name,
2898
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2899
enum {
2900
#include "syscall_types.h"
2901
};
2902
#undef STRUCT
2903
#undef STRUCT_SPECIAL
2904

    
2905
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2906
#define STRUCT_SPECIAL(name)
2907
#include "syscall_types.h"
2908
#undef STRUCT
2909
#undef STRUCT_SPECIAL
2910

    
2911
typedef struct IOCTLEntry {
2912
    unsigned int target_cmd;
2913
    unsigned int host_cmd;
2914
    const char *name;
2915
    int access;
2916
    const argtype arg_type[5];
2917
} IOCTLEntry;
2918

    
2919
#define IOC_R 0x0001
2920
#define IOC_W 0x0002
2921
#define IOC_RW (IOC_R | IOC_W)
2922

    
2923
#define MAX_STRUCT_SIZE 4096
2924

    
2925
static IOCTLEntry ioctl_entries[] = {
2926
#define IOCTL(cmd, access, ...) \
2927
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2928
#include "ioctls.h"
2929
    { 0, 0, },
2930
};
2931

    
2932
/* ??? Implement proper locking for ioctls.  */
2933
/* do_ioctl() Must return target values and target errnos. */
2934
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2935
{
2936
    const IOCTLEntry *ie;
2937
    const argtype *arg_type;
2938
    abi_long ret;
2939
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2940
    int target_size;
2941
    void *argptr;
2942

    
2943
    ie = ioctl_entries;
2944
    for(;;) {
2945
        if (ie->target_cmd == 0) {
2946
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2947
            return -TARGET_ENOSYS;
2948
        }
2949
        if (ie->target_cmd == cmd)
2950
            break;
2951
        ie++;
2952
    }
2953
    arg_type = ie->arg_type;
2954
#if defined(DEBUG)
2955
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2956
#endif
2957
    switch(arg_type[0]) {
2958
    case TYPE_NULL:
2959
        /* no argument */
2960
        ret = get_errno(ioctl(fd, ie->host_cmd));
2961
        break;
2962
    case TYPE_PTRVOID:
2963
    case TYPE_INT:
2964
        /* int argment */
2965
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2966
        break;
2967
    case TYPE_PTR:
2968
        arg_type++;
2969
        target_size = thunk_type_size(arg_type, 0);
2970
        switch(ie->access) {
2971
        case IOC_R:
2972
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2973
            if (!is_error(ret)) {
2974
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2975
                if (!argptr)
2976
                    return -TARGET_EFAULT;
2977
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2978
                unlock_user(argptr, arg, target_size);
2979
            }
2980
            break;
2981
        case IOC_W:
2982
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2983
            if (!argptr)
2984
                return -TARGET_EFAULT;
2985
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2986
            unlock_user(argptr, arg, 0);
2987
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2988
            break;
2989
        default:
2990
        case IOC_RW:
2991
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2992
            if (!argptr)
2993
                return -TARGET_EFAULT;
2994
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2995
            unlock_user(argptr, arg, 0);
2996
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2997
            if (!is_error(ret)) {
2998
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2999
                if (!argptr)
3000
                    return -TARGET_EFAULT;
3001
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3002
                unlock_user(argptr, arg, target_size);
3003
            }
3004
            break;
3005
        }
3006
        break;
3007
    default:
3008
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3009
                 (long)cmd, arg_type[0]);
3010
        ret = -TARGET_ENOSYS;
3011
        break;
3012
    }
3013
    return ret;
3014
}
3015

    
3016
static const bitmask_transtbl iflag_tbl[] = {
3017
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3018
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3019
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3020
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3021
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3022
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3023
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3024
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3025
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3026
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3027
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3028
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3029
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3030
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3031
        { 0, 0, 0, 0 }
3032
};
3033

    
3034
static const bitmask_transtbl oflag_tbl[] = {
3035
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3036
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3037
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3038
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3039
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3040
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3041
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3042
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3043
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3044
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3045
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3046
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3047
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3048
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3049
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3050
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3051
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3052
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3053
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3054
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3055
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3056
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3057
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3058
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3059
        { 0, 0, 0, 0 }
3060
};
3061

    
3062
static const bitmask_transtbl cflag_tbl[] = {
3063
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3064
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3065
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3066
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3067
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3068
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3069
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3070
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3071
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3072
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3073
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3074
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3075
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3076
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3077
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3078
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3079
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3080
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3081
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3082
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3083
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3084
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3085
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3086
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3087
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3088
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3089
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3090
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3091
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3092
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3093
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3094
        { 0, 0, 0, 0 }
3095
};
3096

    
3097
static const bitmask_transtbl lflag_tbl[] = {
3098
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3099
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3100
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3101
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3102
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3103
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3104
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3105
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3106
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3107
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3108
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3109
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3110
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3111
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3112
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3113
        { 0, 0, 0, 0 }
3114
};
3115

    
3116
static void target_to_host_termios (void *dst, const void *src)
3117
{
3118
    struct host_termios *host = dst;
3119
    const struct target_termios *target = src;
3120

    
3121
    host->c_iflag =
3122
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3123
    host->c_oflag =
3124
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3125
    host->c_cflag =
3126
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3127
    host->c_lflag =
3128
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3129
    host->c_line = target->c_line;
3130

    
3131
    memset(host->c_cc, 0, sizeof(host->c_cc));
3132
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3133
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3134
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3135
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3136
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3137
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3138
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3139
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3140
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3141
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3142
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3143
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3144
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3145
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3146
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3147
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3148
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3149
}
3150

    
3151
static void host_to_target_termios (void *dst, const void *src)
3152
{
3153
    struct target_termios *target = dst;
3154
    const struct host_termios *host = src;
3155

    
3156
    target->c_iflag =
3157
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3158
    target->c_oflag =
3159
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3160
    target->c_cflag =
3161
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3162
    target->c_lflag =
3163
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3164
    target->c_line = host->c_line;
3165

    
3166
    memset(target->c_cc, 0, sizeof(target->c_cc));
3167
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3168
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3169
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3170
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3171
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3172
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3173
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3174
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3175
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3176
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3177
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3178
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3179
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3180
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3181
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3182
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3183
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3184
}
3185

    
3186
static const StructEntry struct_termios_def = {
3187
    .convert = { host_to_target_termios, target_to_host_termios },
3188
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3189
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3190
};
3191

    
3192
static bitmask_transtbl mmap_flags_tbl[] = {
3193
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3194
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3195
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3196
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3197
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3198
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3199
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3200
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3201
        { 0, 0, 0, 0 }
3202
};
3203

    
3204
#if defined(TARGET_I386)
3205

    
3206
/* NOTE: there is really one LDT for all the threads */
3207
static uint8_t *ldt_table;
3208

    
3209
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3210
{
3211
    int size;
3212
    void *p;
3213

    
3214
    if (!ldt_table)
3215
        return 0;
3216
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3217
    if (size > bytecount)
3218
        size = bytecount;
3219
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3220
    if (!p)
3221
        return -TARGET_EFAULT;
3222
    /* ??? Should this by byteswapped?  */
3223
    memcpy(p, ldt_table, size);
3224
    unlock_user(p, ptr, size);
3225
    return size;
3226
}
3227

    
3228
/* XXX: add locking support */
3229
static abi_long write_ldt(CPUX86State *env,
3230
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3231
{
3232
    struct target_modify_ldt_ldt_s ldt_info;
3233
    struct target_modify_ldt_ldt_s *target_ldt_info;
3234
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3235
    int seg_not_present, useable, lm;
3236
    uint32_t *lp, entry_1, entry_2;
3237

    
3238
    if (bytecount != sizeof(ldt_info))
3239
        return -TARGET_EINVAL;
3240
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3241
        return -TARGET_EFAULT;
3242
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3243
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3244
    ldt_info.limit = tswap32(target_ldt_info->limit);
3245
    ldt_info.flags = tswap32(target_ldt_info->flags);
3246
    unlock_user_struct(target_ldt_info, ptr, 0);
3247

    
3248
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3249
        return -TARGET_EINVAL;
3250
    seg_32bit = ldt_info.flags & 1;
3251
    contents = (ldt_info.flags >> 1) & 3;
3252
    read_exec_only = (ldt_info.flags >> 3) & 1;
3253
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3254
    seg_not_present = (ldt_info.flags >> 5) & 1;
3255
    useable = (ldt_info.flags >> 6) & 1;
3256
#ifdef TARGET_ABI32
3257
    lm = 0;
3258
#else
3259
    lm = (ldt_info.flags >> 7) & 1;
3260
#endif
3261
    if (contents == 3) {
3262
        if (oldmode)
3263
            return -TARGET_EINVAL;
3264
        if (seg_not_present == 0)
3265
            return -TARGET_EINVAL;
3266
    }
3267
    /* allocate the LDT */
3268
    if (!ldt_table) {
3269
        env->ldt.base = target_mmap(0,
3270
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3271
                                    PROT_READ|PROT_WRITE,
3272
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3273
        if (env->ldt.base == -1)
3274
            return -TARGET_ENOMEM;
3275
        memset(g2h(env->ldt.base), 0,
3276
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3277
        env->ldt.limit = 0xffff;
3278
        ldt_table = g2h(env->ldt.base);
3279
    }
3280

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

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

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

    
3320
/* specific and weird i386 syscalls */
3321
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3322
                              unsigned long bytecount)
3323
{
3324
    abi_long ret;
3325

    
3326
    switch (func) {
3327
    case 0:
3328
        ret = read_ldt(ptr, bytecount);
3329
        break;
3330
    case 1:
3331
        ret = write_ldt(env, ptr, bytecount, 1);
3332
        break;
3333
    case 0x11:
3334
        ret = write_ldt(env, ptr, bytecount, 0);
3335
        break;
3336
    default:
3337
        ret = -TARGET_ENOSYS;
3338
        break;
3339
    }
3340
    return ret;
3341
}
3342

    
3343
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3344
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3345
{
3346
    uint64_t *gdt_table = g2h(env->gdt.base);
3347
    struct target_modify_ldt_ldt_s ldt_info;
3348
    struct target_modify_ldt_ldt_s *target_ldt_info;
3349
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3350
    int seg_not_present, useable, lm;
3351
    uint32_t *lp, entry_1, entry_2;
3352
    int i;
3353

    
3354
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3355
    if (!target_ldt_info)
3356
        return -TARGET_EFAULT;
3357
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3358
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3359
    ldt_info.limit = tswap32(target_ldt_info->limit);
3360
    ldt_info.flags = tswap32(target_ldt_info->flags);
3361
    if (ldt_info.entry_number == -1) {
3362
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3363
            if (gdt_table[i] == 0) {
3364
                ldt_info.entry_number = i;
3365
                target_ldt_info->entry_number = tswap32(i);
3366
                break;
3367
            }
3368
        }
3369
    }
3370
    unlock_user_struct(target_ldt_info, ptr, 1);
3371

    
3372
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3373
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3374
           return -TARGET_EINVAL;
3375
    seg_32bit = ldt_info.flags & 1;
3376
    contents = (ldt_info.flags >> 1) & 3;
3377
    read_exec_only = (ldt_info.flags >> 3) & 1;
3378
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3379
    seg_not_present = (ldt_info.flags >> 5) & 1;
3380
    useable = (ldt_info.flags >> 6) & 1;
3381
#ifdef TARGET_ABI32
3382
    lm = 0;
3383
#else
3384
    lm = (ldt_info.flags >> 7) & 1;
3385
#endif
3386

    
3387
    if (contents == 3) {
3388
        if (seg_not_present == 0)
3389
            return -TARGET_EINVAL;
3390
    }
3391

    
3392
    /* NOTE: same code as Linux kernel */
3393
    /* Allow LDTs to be cleared by the user. */
3394
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3395
        if ((contents == 0             &&
3396
             read_exec_only == 1       &&
3397
             seg_32bit == 0            &&
3398
             limit_in_pages == 0       &&
3399
             seg_not_present == 1      &&
3400
             useable == 0 )) {
3401
            entry_1 = 0;
3402
            entry_2 = 0;
3403
            goto install;
3404
        }
3405
    }
3406

    
3407
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3408
        (ldt_info.limit & 0x0ffff);
3409
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3410
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3411
        (ldt_info.limit & 0xf0000) |
3412
        ((read_exec_only ^ 1) << 9) |
3413
        (contents << 10) |
3414
        ((seg_not_present ^ 1) << 15) |
3415
        (seg_32bit << 22) |
3416
        (limit_in_pages << 23) |
3417
        (useable << 20) |
3418
        (lm << 21) |
3419
        0x7000;
3420

    
3421
    /* Install the new entry ...  */
3422
install:
3423
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3424
    lp[0] = tswap32(entry_1);
3425
    lp[1] = tswap32(entry_2);
3426
    return 0;
3427
}
3428

    
3429
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3430
{
3431
    struct target_modify_ldt_ldt_s *target_ldt_info;
3432
    uint64_t *gdt_table = g2h(env->gdt.base);
3433
    uint32_t base_addr, limit, flags;
3434
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3435
    int seg_not_present, useable, lm;
3436
    uint32_t *lp, entry_1, entry_2;
3437

    
3438
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3439
    if (!target_ldt_info)
3440
        return -TARGET_EFAULT;
3441
    idx = tswap32(target_ldt_info->entry_number);
3442
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3443
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3444
        unlock_user_struct(target_ldt_info, ptr, 1);
3445
        return -TARGET_EINVAL;
3446
    }
3447
    lp = (uint32_t *)(gdt_table + idx);
3448
    entry_1 = tswap32(lp[0]);
3449
    entry_2 = tswap32(lp[1]);
3450
    
3451
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3452
    contents = (entry_2 >> 10) & 3;
3453
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3454
    seg_32bit = (entry_2 >> 22) & 1;
3455
    limit_in_pages = (entry_2 >> 23) & 1;
3456
    useable = (entry_2 >> 20) & 1;
3457
#ifdef TARGET_ABI32
3458
    lm = 0;
3459
#else
3460
    lm = (entry_2 >> 21) & 1;
3461
#endif
3462
    flags = (seg_32bit << 0) | (contents << 1) |
3463
        (read_exec_only << 3) | (limit_in_pages << 4) |
3464
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3465
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3466
    base_addr = (entry_1 >> 16) | 
3467
        (entry_2 & 0xff000000) | 
3468
        ((entry_2 & 0xff) << 16);
3469
    target_ldt_info->base_addr = tswapl(base_addr);
3470
    target_ldt_info->limit = tswap32(limit);
3471
    target_ldt_info->flags = tswap32(flags);
3472
    unlock_user_struct(target_ldt_info, ptr, 1);
3473
    return 0;
3474
}
3475
#endif /* TARGET_I386 && TARGET_ABI32 */
3476

    
3477
#ifndef TARGET_ABI32
3478
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3479
{
3480
    abi_long ret;
3481
    abi_ulong val;
3482
    int idx;
3483
    
3484
    switch(code) {
3485
    case TARGET_ARCH_SET_GS:
3486
    case TARGET_ARCH_SET_FS:
3487
        if (code == TARGET_ARCH_SET_GS)
3488
            idx = R_GS;
3489
        else
3490
            idx = R_FS;
3491
        cpu_x86_load_seg(env, idx, 0);
3492
        env->segs[idx].base = addr;
3493
        break;
3494
    case TARGET_ARCH_GET_GS:
3495
    case TARGET_ARCH_GET_FS:
3496
        if (code == TARGET_ARCH_GET_GS)
3497
            idx = R_GS;
3498
        else
3499
            idx = R_FS;
3500
        val = env->segs[idx].base;
3501
        if (put_user(val, addr, abi_ulong))
3502
            return -TARGET_EFAULT;
3503
        break;
3504
    default:
3505
        ret = -TARGET_EINVAL;
3506
        break;
3507
    }
3508
    return 0;
3509
}
3510
#endif
3511

    
3512
#endif /* defined(TARGET_I386) */
3513

    
3514
#if defined(CONFIG_USE_NPTL)
3515

    
3516
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3517

    
3518
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3519
typedef struct {
3520
    CPUState *env;
3521
    pthread_mutex_t mutex;
3522
    pthread_cond_t cond;
3523
    pthread_t thread;
3524
    uint32_t tid;
3525
    abi_ulong child_tidptr;
3526
    abi_ulong parent_tidptr;
3527
    sigset_t sigmask;
3528
} new_thread_info;
3529

    
3530
static void *clone_func(void *arg)
3531
{
3532
    new_thread_info *info = arg;
3533
    CPUState *env;
3534
    TaskState *ts;
3535

    
3536
    env = info->env;
3537
    thread_env = env;
3538
    ts = (TaskState *)thread_env->opaque;
3539
    info->tid = gettid();
3540
    env->host_tid = info->tid;
3541
    task_settid(ts);
3542
    if (info->child_tidptr)
3543
        put_user_u32(info->tid, info->child_tidptr);
3544
    if (info->parent_tidptr)
3545
        put_user_u32(info->tid, info->parent_tidptr);
3546
    /* Enable signals.  */
3547
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3548
    /* Signal to the parent that we're ready.  */
3549
    pthread_mutex_lock(&info->mutex);
3550
    pthread_cond_broadcast(&info->cond);
3551
    pthread_mutex_unlock(&info->mutex);
3552
    /* Wait until the parent has finshed initializing the tls state.  */
3553
    pthread_mutex_lock(&clone_lock);
3554
    pthread_mutex_unlock(&clone_lock);
3555
    cpu_loop(env);
3556
    /* never exits */
3557
    return NULL;
3558
}
3559
#else
3560
/* this stack is the equivalent of the kernel stack associated with a
3561
   thread/process */
3562
#define NEW_STACK_SIZE 8192
3563

    
3564
static int clone_func(void *arg)
3565
{
3566
    CPUState *env = arg;
3567
    cpu_loop(env);
3568
    /* never exits */
3569
    return 0;
3570
}
3571
#endif
3572

    
3573
/* do_fork() Must return host values and target errnos (unlike most
3574
   do_*() functions). */
3575
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3576
                   abi_ulong parent_tidptr, target_ulong newtls,
3577
                   abi_ulong child_tidptr)
3578
{
3579
    int ret;
3580
    TaskState *ts;
3581
    uint8_t *new_stack;
3582
    CPUState *new_env;
3583
#if defined(CONFIG_USE_NPTL)
3584
    unsigned int nptl_flags;
3585
    sigset_t sigmask;
3586
#endif
3587

    
3588
    /* Emulate vfork() with fork() */
3589
    if (flags & CLONE_VFORK)
3590
        flags &= ~(CLONE_VFORK | CLONE_VM);
3591

    
3592
    if (flags & CLONE_VM) {
3593
        TaskState *parent_ts = (TaskState *)env->opaque;
3594
#if defined(CONFIG_USE_NPTL)
3595
        new_thread_info info;
3596
        pthread_attr_t attr;
3597
#endif
3598
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3599
        init_task_state(ts);
3600
        new_stack = ts->stack;
3601
        /* we create a new CPU instance. */
3602
        new_env = cpu_copy(env);
3603
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3604
        cpu_reset(new_env);
3605
#endif
3606
        /* Init regs that differ from the parent.  */
3607
        cpu_clone_regs(new_env, newsp);
3608
        new_env->opaque = ts;
3609
        ts->bprm = parent_ts->bprm;
3610
        ts->info = parent_ts->info;
3611
#if defined(CONFIG_USE_NPTL)
3612
        nptl_flags = flags;
3613
        flags &= ~CLONE_NPTL_FLAGS2;
3614

    
3615
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3616
            ts->child_tidptr = child_tidptr;
3617
        }
3618

    
3619
        if (nptl_flags & CLONE_SETTLS)
3620
            cpu_set_tls (new_env, newtls);
3621

    
3622
        /* Grab a mutex so that thread setup appears atomic.  */
3623
        pthread_mutex_lock(&clone_lock);
3624

    
3625
        memset(&info, 0, sizeof(info));
3626
        pthread_mutex_init(&info.mutex, NULL);
3627
        pthread_mutex_lock(&info.mutex);
3628
        pthread_cond_init(&info.cond, NULL);
3629
        info.env = new_env;
3630
        if (nptl_flags & CLONE_CHILD_SETTID)
3631
            info.child_tidptr = child_tidptr;
3632
        if (nptl_flags & CLONE_PARENT_SETTID)
3633
            info.parent_tidptr = parent_tidptr;
3634

    
3635
        ret = pthread_attr_init(&attr);
3636
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3637
        /* It is not safe to deliver signals until the child has finished
3638
           initializing, so temporarily block all signals.  */
3639
        sigfillset(&sigmask);
3640
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3641

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

    
3645
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3646
        pthread_attr_destroy(&attr);
3647
        if (ret == 0) {
3648
            /* Wait for the child to initialize.  */
3649
            pthread_cond_wait(&info.cond, &info.mutex);
3650
            ret = info.tid;
3651
            if (flags & CLONE_PARENT_SETTID)
3652
                put_user_u32(ret, parent_tidptr);
3653
        } else {
3654
            ret = -1;
3655
        }
3656
        pthread_mutex_unlock(&info.mutex);
3657
        pthread_cond_destroy(&info.cond);
3658
        pthread_mutex_destroy(&info.mutex);
3659
        pthread_mutex_unlock(&clone_lock);
3660
#else
3661
        if (flags & CLONE_NPTL_FLAGS2)
3662
            return -EINVAL;
3663
        /* This is probably going to die very quickly, but do it anyway.  */
3664
#ifdef __ia64__
3665
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
3666
#else
3667
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3668
#endif
3669
#endif
3670
    } else {
3671
        /* if no CLONE_VM, we consider it is a fork */
3672
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3673
            return -EINVAL;
3674
        fork_start();
3675
        ret = fork();
3676
        if (ret == 0) {
3677
            /* Child Process.  */
3678
            cpu_clone_regs(env, newsp);
3679
            fork_end(1);
3680
#if defined(CONFIG_USE_NPTL)
3681
            /* There is a race condition here.  The parent process could
3682
               theoretically read the TID in the child process before the child
3683
               tid is set.  This would require using either ptrace
3684
               (not implemented) or having *_tidptr to point at a shared memory
3685
               mapping.  We can't repeat the spinlock hack used above because
3686
               the child process gets its own copy of the lock.  */
3687
            if (flags & CLONE_CHILD_SETTID)
3688
                put_user_u32(gettid(), child_tidptr);
3689
            if (flags & CLONE_PARENT_SETTID)
3690
                put_user_u32(gettid(), parent_tidptr);
3691
            ts = (TaskState *)env->opaque;
3692
            if (flags & CLONE_SETTLS)
3693
                cpu_set_tls (env, newtls);
3694
            if (flags & CLONE_CHILD_CLEARTID)
3695
                ts->child_tidptr = child_tidptr;
3696
#endif
3697
        } else {
3698
            fork_end(0);
3699
        }
3700
    }
3701
    return ret;
3702
}
3703

    
3704
/* warning : doesn't handle linux specific flags... */
3705
static int target_to_host_fcntl_cmd(int cmd)
3706
{
3707
    switch(cmd) {
3708
        case TARGET_F_DUPFD:
3709
        case TARGET_F_GETFD:
3710
        case TARGET_F_SETFD:
3711
        case TARGET_F_GETFL:
3712
        case TARGET_F_SETFL:
3713
            return cmd;
3714
        case TARGET_F_GETLK:
3715
            return F_GETLK;
3716
        case TARGET_F_SETLK:
3717
            return F_SETLK;
3718
        case TARGET_F_SETLKW:
3719
            return F_SETLKW;
3720
        case TARGET_F_GETOWN:
3721
            return F_GETOWN;
3722
        case TARGET_F_SETOWN:
3723
            return F_SETOWN;
3724
        case TARGET_F_GETSIG:
3725
            return F_GETSIG;
3726
        case TARGET_F_SETSIG:
3727
            return F_SETSIG;
3728
#if TARGET_ABI_BITS == 32
3729
        case TARGET_F_GETLK64:
3730
            return F_GETLK64;
3731
        case TARGET_F_SETLK64:
3732
            return F_SETLK64;
3733
        case TARGET_F_SETLKW64:
3734
            return F_SETLKW64;
3735
#endif
3736
        case TARGET_F_SETLEASE:
3737
            return F_SETLEASE;
3738
        case TARGET_F_GETLEASE:
3739
            return F_GETLEASE;
3740
#ifdef F_DUPFD_CLOEXEC
3741
        case TARGET_F_DUPFD_CLOEXEC:
3742
            return F_DUPFD_CLOEXEC;
3743
#endif
3744
        case TARGET_F_NOTIFY:
3745
            return F_NOTIFY;
3746
        default:
3747
            return -TARGET_EINVAL;
3748
    }
3749
    return -TARGET_EINVAL;
3750
}
3751

    
3752
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3753
{
3754
    struct flock fl;
3755
    struct target_flock *target_fl;
3756
    struct flock64 fl64;
3757
    struct target_flock64 *target_fl64;
3758
    abi_long ret;
3759
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3760

    
3761
    if (host_cmd == -TARGET_EINVAL)
3762
            return host_cmd;
3763

    
3764
    switch(cmd) {
3765
    case TARGET_F_GETLK:
3766
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3767
            return -TARGET_EFAULT;
3768
        fl.l_type = tswap16(target_fl->l_type);
3769
        fl.l_whence = tswap16(target_fl->l_whence);
3770
        fl.l_start = tswapl(target_fl->l_start);
3771
        fl.l_len = tswapl(target_fl->l_len);
3772
        fl.l_pid = tswap32(target_fl->l_pid);
3773
        unlock_user_struct(target_fl, arg, 0);
3774
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3775
        if (ret == 0) {
3776
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3777
                return -TARGET_EFAULT;
3778
            target_fl->l_type = tswap16(fl.l_type);
3779
            target_fl->l_whence = tswap16(fl.l_whence);
3780
            target_fl->l_start = tswapl(fl.l_start);
3781
            target_fl->l_len = tswapl(fl.l_len);
3782
            target_fl->l_pid = tswap32(fl.l_pid);
3783
            unlock_user_struct(target_fl, arg, 1);
3784
        }
3785
        break;
3786

    
3787
    case TARGET_F_SETLK:
3788
    case TARGET_F_SETLKW:
3789
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3790
            return -TARGET_EFAULT;
3791
        fl.l_type = tswap16(target_fl->l_type);
3792
        fl.l_whence = tswap16(target_fl->l_whence);
3793
        fl.l_start = tswapl(target_fl->l_start);
3794
        fl.l_len = tswapl(target_fl->l_len);
3795
        fl.l_pid = tswap32(target_fl->l_pid);
3796
        unlock_user_struct(target_fl, arg, 0);
3797
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3798
        break;
3799

    
3800
    case TARGET_F_GETLK64:
3801
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3802
            return -TARGET_EFAULT;
3803
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3804
        fl64.l_whence = tswap16(target_fl64->l_whence);
3805
        fl64.l_start = tswapl(target_fl64->l_start);
3806
        fl64.l_len = tswapl(target_fl64->l_len);
3807
        fl64.l_pid = tswap32(target_fl64->l_pid);
3808
        unlock_user_struct(target_fl64, arg, 0);
3809
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3810
        if (ret == 0) {
3811
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3812
                return -TARGET_EFAULT;
3813
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3814
            target_fl64->l_whence = tswap16(fl64.l_whence);
3815
            target_fl64->l_start = tswapl(fl64.l_start);
3816
            target_fl64->l_len = tswapl(fl64.l_len);
3817
            target_fl64->l_pid = tswap32(fl64.l_pid);
3818
            unlock_user_struct(target_fl64, arg, 1);
3819
        }
3820
        break;
3821
    case TARGET_F_SETLK64:
3822
    case TARGET_F_SETLKW64:
3823
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3824
            return -TARGET_EFAULT;
3825
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3826
        fl64.l_whence = tswap16(target_fl64->l_whence);
3827
        fl64.l_start = tswapl(target_fl64->l_start);
3828
        fl64.l_len = tswapl(target_fl64->l_len);
3829
        fl64.l_pid = tswap32(target_fl64->l_pid);
3830
        unlock_user_struct(target_fl64, arg, 0);
3831
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3832
        break;
3833

    
3834
    case TARGET_F_GETFL:
3835
        ret = get_errno(fcntl(fd, host_cmd, arg));
3836
        if (ret >= 0) {
3837
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3838
        }
3839
        break;
3840

    
3841
    case TARGET_F_SETFL:
3842
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3843
        break;
3844

    
3845
    case TARGET_F_SETOWN:
3846
    case TARGET_F_GETOWN:
3847
    case TARGET_F_SETSIG:
3848
    case TARGET_F_GETSIG:
3849
    case TARGET_F_SETLEASE:
3850
    case TARGET_F_GETLEASE:
3851
        ret = get_errno(fcntl(fd, host_cmd, arg));
3852
        break;
3853

    
3854
    default:
3855
        ret = get_errno(fcntl(fd, cmd, arg));
3856
        break;
3857
    }
3858
    return ret;
3859
}
3860

    
3861
#ifdef USE_UID16
3862

    
3863
static inline int high2lowuid(int uid)
3864
{
3865
    if (uid > 65535)
3866
        return 65534;
3867
    else
3868
        return uid;
3869
}
3870

    
3871
static inline int high2lowgid(int gid)
3872
{
3873
    if (gid > 65535)
3874
        return 65534;
3875
    else
3876
        return gid;
3877
}
3878

    
3879
static inline int low2highuid(int uid)
3880
{
3881
    if ((int16_t)uid == -1)
3882
        return -1;
3883
    else
3884
        return uid;
3885
}
3886

    
3887
static inline int low2highgid(int gid)
3888
{
3889
    if ((int16_t)gid == -1)
3890
        return -1;
3891
    else
3892
        return gid;
3893
}
3894

    
3895
#endif /* USE_UID16 */
3896

    
3897
void syscall_init(void)
3898
{
3899
    IOCTLEntry *ie;
3900
    const argtype *arg_type;
3901
    int size;
3902
    int i;
3903

    
3904
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3905
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3906
#include "syscall_types.h"
3907
#undef STRUCT
3908
#undef STRUCT_SPECIAL
3909

    
3910
    /* we patch the ioctl size if necessary. We rely on the fact that
3911
       no ioctl has all the bits at '1' in the size field */
3912
    ie = ioctl_entries;
3913
    while (ie->target_cmd != 0) {
3914
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3915
            TARGET_IOC_SIZEMASK) {
3916
            arg_type = ie->arg_type;
3917
            if (arg_type[0] != TYPE_PTR) {
3918
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3919
                        ie->target_cmd);
3920
                exit(1);
3921
            }
3922
            arg_type++;
3923
            size = thunk_type_size(arg_type, 0);
3924
            ie->target_cmd = (ie->target_cmd &
3925
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3926
                (size << TARGET_IOC_SIZESHIFT);
3927
        }
3928

    
3929
        /* Build target_to_host_errno_table[] table from
3930
         * host_to_target_errno_table[]. */
3931
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3932
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3933

    
3934
        /* automatic consistency check if same arch */
3935
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3936
    (defined(__x86_64__) && defined(TARGET_X86_64))
3937
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3938
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3939
                    ie->name, ie->target_cmd, ie->host_cmd);
3940
        }
3941
#endif
3942
        ie++;
3943
    }
3944
}
3945

    
3946
#if TARGET_ABI_BITS == 32
3947
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3948
{
3949
#ifdef TARGET_WORDS_BIGENDIAN
3950
    return ((uint64_t)word0 << 32) | word1;
3951
#else
3952
    return ((uint64_t)word1 << 32) | word0;
3953
#endif
3954
}
3955
#else /* TARGET_ABI_BITS == 32 */
3956
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3957
{
3958
    return word0;
3959
}
3960
#endif /* TARGET_ABI_BITS != 32 */
3961

    
3962
#ifdef TARGET_NR_truncate64
3963
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3964
                                         abi_long arg2,
3965
                                         abi_long arg3,
3966
                                         abi_long arg4)
3967
{
3968
#ifdef TARGET_ARM
3969
    if (((CPUARMState *)cpu_env)->eabi)
3970
      {
3971
        arg2 = arg3;
3972
        arg3 = arg4;
3973
      }
3974
#endif
3975
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3976
}
3977
#endif
3978

    
3979
#ifdef TARGET_NR_ftruncate64
3980
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3981
                                          abi_long arg2,
3982
                                          abi_long arg3,
3983
                                          abi_long arg4)
3984
{
3985
#ifdef TARGET_ARM
3986
    if (((CPUARMState *)cpu_env)->eabi)
3987
      {
3988
        arg2 = arg3;
3989
        arg3 = arg4;
3990
      }
3991
#endif
3992
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3993
}
3994
#endif
3995

    
3996
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3997
                                               abi_ulong target_addr)
3998
{
3999
    struct target_timespec *target_ts;
4000

    
4001
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4002
        return -TARGET_EFAULT;
4003
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
4004
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
4005
    unlock_user_struct(target_ts, target_addr, 0);
4006
    return 0;
4007
}
4008

    
4009
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4010
                                               struct timespec *host_ts)
4011
{
4012
    struct target_timespec *target_ts;
4013

    
4014
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4015
        return -TARGET_EFAULT;
4016
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
4017
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
4018
    unlock_user_struct(target_ts, target_addr, 1);
4019
    return 0;
4020
}
4021

    
4022
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4023
static inline abi_long host_to_target_stat64(void *cpu_env,
4024
                                             abi_ulong target_addr,
4025
                                             struct stat *host_st)
4026
{
4027
#ifdef TARGET_ARM
4028
    if (((CPUARMState *)cpu_env)->eabi) {
4029
        struct target_eabi_stat64 *target_st;
4030

    
4031
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4032
            return -TARGET_EFAULT;
4033
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4034
        __put_user(host_st->st_dev, &target_st->st_dev);
4035
        __put_user(host_st->st_ino, &target_st->st_ino);
4036
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4037
        __put_user(host_st->st_ino, &target_st->__st_ino);
4038
#endif
4039
        __put_user(host_st->st_mode, &target_st->st_mode);
4040
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4041
        __put_user(host_st->st_uid, &target_st->st_uid);
4042
        __put_user(host_st->st_gid, &target_st->st_gid);
4043
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4044
        __put_user(host_st->st_size, &target_st->st_size);
4045
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4046
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4047
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4048
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4049
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4050
        unlock_user_struct(target_st, target_addr, 1);
4051
    } else
4052
#endif
4053
    {
4054
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4055
        struct target_stat *target_st;
4056
#else
4057
        struct target_stat64 *target_st;
4058
#endif
4059

    
4060
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4061
            return -TARGET_EFAULT;
4062
        memset(target_st, 0, sizeof(*target_st));
4063
        __put_user(host_st->st_dev, &target_st->st_dev);
4064
        __put_user(host_st->st_ino, &target_st->st_ino);
4065
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4066
        __put_user(host_st->st_ino, &target_st->__st_ino);
4067
#endif
4068
        __put_user(host_st->st_mode, &target_st->st_mode);
4069
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4070
        __put_user(host_st->st_uid, &target_st->st_uid);
4071
        __put_user(host_st->st_gid, &target_st->st_gid);
4072
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4073
        /* XXX: better use of kernel struct */
4074
        __put_user(host_st->st_size, &target_st->st_size);
4075
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4076
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4077
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4078
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4079
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4080
        unlock_user_struct(target_st, target_addr, 1);
4081
    }
4082

    
4083
    return 0;
4084
}
4085
#endif
4086

    
4087
#if defined(CONFIG_USE_NPTL)
4088
/* ??? Using host futex calls even when target atomic operations
4089
   are not really atomic probably breaks things.  However implementing
4090
   futexes locally would make futexes shared between multiple processes
4091
   tricky.  However they're probably useless because guest atomic
4092
   operations won't work either.  */
4093
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4094
                    target_ulong uaddr2, int val3)
4095
{
4096
    struct timespec ts, *pts;
4097
    int base_op;
4098

    
4099
    /* ??? We assume FUTEX_* constants are the same on both host
4100
       and target.  */
4101
#ifdef FUTEX_CMD_MASK
4102
    base_op = op & FUTEX_CMD_MASK;
4103
#else
4104
    base_op = op;
4105
#endif
4106
    switch (base_op) {
4107
    case FUTEX_WAIT:
4108
        if (timeout) {
4109
            pts = &ts;
4110
            target_to_host_timespec(pts, timeout);
4111
        } else {
4112
            pts = NULL;
4113
        }
4114
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4115
                         pts, NULL, 0));
4116
    case FUTEX_WAKE:
4117
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4118
    case FUTEX_FD:
4119
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4120
    case FUTEX_REQUEUE:
4121
    case FUTEX_CMP_REQUEUE:
4122
    case FUTEX_WAKE_OP:
4123
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4124
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4125
           But the prototype takes a `struct timespec *'; insert casts
4126
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4127
           since it's not compared to guest memory.  */
4128
        pts = (struct timespec *)(uintptr_t) timeout;
4129
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4130
                                   g2h(uaddr2),
4131
                                   (base_op == FUTEX_CMP_REQUEUE
4132
                                    ? tswap32(val3)
4133
                                    : val3)));
4134
    default:
4135
        return -TARGET_ENOSYS;
4136
    }
4137
}
4138
#endif
4139

    
4140
/* Map host to target signal numbers for the wait family of syscalls.
4141
   Assume all other status bits are the same.  */
4142
static int host_to_target_waitstatus(int status)
4143
{
4144
    if (WIFSIGNALED(status)) {
4145
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4146
    }
4147
    if (WIFSTOPPED(status)) {
4148
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4149
               | (status & 0xff);
4150
    }
4151
    return status;
4152
}
4153

    
4154
int get_osversion(void)
4155
{
4156
    static int osversion;
4157
    struct new_utsname buf;
4158
    const char *s;
4159
    int i, n, tmp;
4160
    if (osversion)
4161
        return osversion;
4162
    if (qemu_uname_release && *qemu_uname_release) {
4163
        s = qemu_uname_release;
4164
    } else {
4165
        if (sys_uname(&buf))
4166
            return 0;
4167
        s = buf.release;
4168
    }
4169
    tmp = 0;
4170
    for (i = 0; i < 3; i++) {
4171
        n = 0;
4172
        while (*s >= '0' && *s <= '9') {
4173
            n *= 10;
4174
            n += *s - '0';
4175
            s++;
4176
        }
4177
        tmp = (tmp << 8) + n;
4178
        if (*s == '.')
4179
            s++;
4180
    }
4181
    osversion = tmp;
4182
    return osversion;
4183
}
4184

    
4185
/* do_syscall() should always have a single exit point at the end so
4186
   that actions, such as logging of syscall results, can be performed.
4187
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4188
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4189
                    abi_long arg2, abi_long arg3, abi_long arg4,
4190
                    abi_long arg5, abi_long arg6)
4191
{
4192
    abi_long ret;
4193
    struct stat st;
4194
    struct statfs stfs;
4195
    void *p;
4196

    
4197
#ifdef DEBUG
4198
    gemu_log("syscall %d", num);
4199
#endif
4200
    if(do_strace)
4201
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4202

    
4203
    switch(num) {
4204
    case TARGET_NR_exit:
4205
#ifdef CONFIG_USE_NPTL
4206
      /* In old applications this may be used to implement _exit(2).
4207
         However in threaded applictions it is used for thread termination,
4208
         and _exit_group is used for application termination.
4209
         Do thread termination if we have more then one thread.  */
4210
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4211
         be disabling signals.  */
4212
      if (first_cpu->next_cpu) {
4213
          TaskState *ts;
4214
          CPUState **lastp;
4215
          CPUState *p;
4216

    
4217
          cpu_list_lock();
4218
          lastp = &first_cpu;
4219
          p = first_cpu;
4220
          while (p && p != (CPUState *)cpu_env) {
4221
              lastp = &p->next_cpu;
4222
              p = p->next_cpu;
4223
          }
4224
          /* If we didn't find the CPU for this thread then something is
4225
             horribly wrong.  */
4226
          if (!p)
4227
              abort();
4228
          /* Remove the CPU from the list.  */
4229
          *lastp = p->next_cpu;
4230
          cpu_list_unlock();
4231
          ts = ((CPUState *)cpu_env)->opaque;
4232
          if (ts->child_tidptr) {
4233
              put_user_u32(0, ts->child_tidptr);
4234
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4235
                        NULL, NULL, 0);
4236
          }
4237
          /* TODO: Free CPU state.  */
4238
          pthread_exit(NULL);
4239
      }
4240
#endif
4241
#ifdef TARGET_GPROF
4242
        _mcleanup();
4243
#endif
4244
        gdb_exit(cpu_env, arg1);
4245
        _exit(arg1);
4246
        ret = 0; /* avoid warning */
4247
        break;
4248
    case TARGET_NR_read:
4249
        if (arg3 == 0)
4250
            ret = 0;
4251
        else {
4252
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4253
                goto efault;
4254
            ret = get_errno(read(arg1, p, arg3));
4255
            unlock_user(p, arg2, ret);
4256
        }
4257
        break;
4258
    case TARGET_NR_write:
4259
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4260
            goto efault;
4261
        ret = get_errno(write(arg1, p, arg3));
4262
        unlock_user(p, arg2, 0);
4263
        break;
4264
    case TARGET_NR_open:
4265
        if (!(p = lock_user_string(arg1)))
4266
            goto efault;
4267
        ret = get_errno(open(path(p),
4268
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4269
                             arg3));
4270
        unlock_user(p, arg1, 0);
4271
        break;
4272
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4273
    case TARGET_NR_openat:
4274
        if (!(p = lock_user_string(arg2)))
4275
            goto efault;
4276
        ret = get_errno(sys_openat(arg1,
4277
                                   path(p),
4278
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4279
                                   arg4));
4280
        unlock_user(p, arg2, 0);
4281
        break;
4282
#endif
4283
    case TARGET_NR_close:
4284
        ret = get_errno(close(arg1));
4285
        break;
4286
    case TARGET_NR_brk:
4287
        ret = do_brk(arg1);
4288
        break;
4289
    case TARGET_NR_fork:
4290
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4291
        break;
4292
#ifdef TARGET_NR_waitpid
4293
    case TARGET_NR_waitpid:
4294
        {
4295
            int status;
4296
            ret = get_errno(waitpid(arg1, &status, arg3));
4297
            if (!is_error(ret) && arg2
4298
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4299
                goto efault;
4300
        }
4301
        break;
4302
#endif
4303
#ifdef TARGET_NR_waitid
4304
    case TARGET_NR_waitid:
4305
        {
4306
            siginfo_t info;
4307
            info.si_pid = 0;
4308
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4309
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4310
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4311
                    goto efault;
4312
                host_to_target_siginfo(p, &info);
4313
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4314
            }
4315
        }
4316
        break;
4317
#endif
4318
#ifdef TARGET_NR_creat /* not on alpha */
4319
    case TARGET_NR_creat:
4320
        if (!(p = lock_user_string(arg1)))
4321
            goto efault;
4322
        ret = get_errno(creat(p, arg2));
4323
        unlock_user(p, arg1, 0);
4324
        break;
4325
#endif
4326
    case TARGET_NR_link:
4327
        {
4328
            void * p2;
4329
            p = lock_user_string(arg1);
4330
            p2 = lock_user_string(arg2);
4331
            if (!p || !p2)
4332
                ret = -TARGET_EFAULT;
4333
            else
4334
                ret = get_errno(link(p, p2));
4335
            unlock_user(p2, arg2, 0);
4336
            unlock_user(p, arg1, 0);
4337
        }
4338
        break;
4339
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4340
    case TARGET_NR_linkat:
4341
        {
4342
            void * p2 = NULL;
4343
            if (!arg2 || !arg4)
4344
                goto efault;
4345
            p  = lock_user_string(arg2);
4346
            p2 = lock_user_string(arg4);
4347
            if (!p || !p2)
4348
                ret = -TARGET_EFAULT;
4349
            else
4350
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4351
            unlock_user(p, arg2, 0);
4352
            unlock_user(p2, arg4, 0);
4353
        }
4354
        break;
4355
#endif
4356
    case TARGET_NR_unlink:
4357
        if (!(p = lock_user_string(arg1)))
4358
            goto efault;
4359
        ret = get_errno(unlink(p));
4360
        unlock_user(p, arg1, 0);
4361
        break;
4362
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4363
    case TARGET_NR_unlinkat:
4364
        if (!(p = lock_user_string(arg2)))
4365
            goto efault;
4366
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4367
        unlock_user(p, arg2, 0);
4368
        break;
4369
#endif
4370
    case TARGET_NR_execve:
4371
        {
4372
            char **argp, **envp;
4373
            int argc, envc;
4374
            abi_ulong gp;
4375
            abi_ulong guest_argp;
4376
            abi_ulong guest_envp;
4377
            abi_ulong addr;
4378
            char **q;
4379

    
4380
            argc = 0;
4381
            guest_argp = arg2;
4382
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4383
                if (get_user_ual(addr, gp))
4384
                    goto efault;
4385
                if (!addr)
4386
                    break;
4387
                argc++;
4388
            }
4389
            envc = 0;
4390
            guest_envp = arg3;
4391
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4392
                if (get_user_ual(addr, gp))
4393
                    goto efault;
4394
                if (!addr)
4395
                    break;
4396
                envc++;
4397
            }
4398

    
4399
            argp = alloca((argc + 1) * sizeof(void *));
4400
            envp = alloca((envc + 1) * sizeof(void *));
4401

    
4402
            for (gp = guest_argp, q = argp; gp;
4403
                  gp += sizeof(abi_ulong), q++) {
4404
                if (get_user_ual(addr, gp))
4405
                    goto execve_efault;
4406
                if (!addr)
4407
                    break;
4408
                if (!(*q = lock_user_string(addr)))
4409
                    goto execve_efault;
4410
            }
4411
            *q = NULL;
4412

    
4413
            for (gp = guest_envp, q = envp; gp;
4414
                  gp += sizeof(abi_ulong), q++) {
4415
                if (get_user_ual(addr, gp))
4416
                    goto execve_efault;
4417
                if (!addr)
4418
                    break;
4419
                if (!(*q = lock_user_string(addr)))
4420
                    goto execve_efault;
4421
            }
4422
            *q = NULL;
4423

    
4424
            if (!(p = lock_user_string(arg1)))
4425
                goto execve_efault;
4426
            ret = get_errno(execve(p, argp, envp));
4427
            unlock_user(p, arg1, 0);
4428

    
4429
            goto execve_end;
4430

    
4431
        execve_efault:
4432
            ret = -TARGET_EFAULT;
4433

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

    
4854
            if (arg2) {
4855
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4856
                    goto efault;
4857
                act._sa_handler = old_act->_sa_handler;
4858
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4859
                act.sa_flags = old_act->sa_flags;
4860
                unlock_user_struct(old_act, arg2, 0);
4861
                pact = &act;
4862
            } else {
4863
                pact = NULL;
4864
            }
4865

    
4866
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4867

    
4868
            if (!is_error(ret) && arg3) {
4869
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4870
                    goto efault;
4871
                old_act->_sa_handler = oact._sa_handler;
4872
                old_act->sa_flags = oact.sa_flags;
4873
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4874
                old_act->sa_mask.sig[1] = 0;
4875
                old_act->sa_mask.sig[2] = 0;
4876
                old_act->sa_mask.sig[3] = 0;
4877
                unlock_user_struct(old_act, arg3, 1);
4878
            }
4879
#else
4880
            struct target_old_sigaction *old_act;
4881
            struct target_sigaction act, oact, *pact;
4882
            if (arg2) {
4883
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4884
                    goto efault;
4885
                act._sa_handler = old_act->_sa_handler;
4886
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4887
                act.sa_flags = old_act->sa_flags;
4888
                act.sa_restorer = old_act->sa_restorer;
4889
                unlock_user_struct(old_act, arg2, 0);
4890
                pact = &act;
4891
            } else {
4892
                pact = NULL;
4893
            }
4894
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4895
            if (!is_error(ret) && arg3) {
4896
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4897
                    goto efault;
4898
                old_act->_sa_handler = oact._sa_handler;
4899
                old_act->sa_mask = oact.sa_mask.sig[0];
4900
                old_act->sa_flags = oact.sa_flags;
4901
                old_act->sa_restorer = oact.sa_restorer;
4902
                unlock_user_struct(old_act, arg3, 1);
4903
            }
4904
#endif
4905
        }
4906
        break;
4907
#endif
4908
    case TARGET_NR_rt_sigaction:
4909
        {
4910
#if defined(TARGET_ALPHA)
4911
            struct target_sigaction act, oact, *pact = 0;
4912
            struct target_rt_sigaction *rt_act;
4913
            /* ??? arg4 == sizeof(sigset_t).  */
4914
            if (arg2) {
4915
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
4916
                    goto efault;
4917
                act._sa_handler = rt_act->_sa_handler;
4918
                act.sa_mask = rt_act->sa_mask;
4919
                act.sa_flags = rt_act->sa_flags;
4920
                act.sa_restorer = arg5;
4921
                unlock_user_struct(rt_act, arg2, 0);
4922
                pact = &act;
4923
            }
4924
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4925
            if (!is_error(ret) && arg3) {
4926
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
4927
                    goto efault;
4928
                rt_act->_sa_handler = oact._sa_handler;
4929
                rt_act->sa_mask = oact.sa_mask;
4930
                rt_act->sa_flags = oact.sa_flags;
4931
                unlock_user_struct(rt_act, arg3, 1);
4932
            }
4933
#else
4934
            struct target_sigaction *act;
4935
            struct target_sigaction *oact;
4936

    
4937
            if (arg2) {
4938
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4939
                    goto efault;
4940
            } else
4941
                act = NULL;
4942
            if (arg3) {
4943
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4944
                    ret = -TARGET_EFAULT;
4945
                    goto rt_sigaction_fail;
4946
                }
4947
            } else
4948
                oact = NULL;
4949
            ret = get_errno(do_sigaction(arg1, act, oact));
4950
        rt_sigaction_fail:
4951
            if (act)
4952
                unlock_user_struct(act, arg2, 0);
4953
            if (oact)
4954
                unlock_user_struct(oact, arg3, 1);
4955
#endif
4956
        }
4957
        break;
4958
#ifdef TARGET_NR_sgetmask /* not on alpha */
4959
    case TARGET_NR_sgetmask:
4960
        {
4961
            sigset_t cur_set;
4962
            abi_ulong target_set;
4963
            sigprocmask(0, NULL, &cur_set);
4964
            host_to_target_old_sigset(&target_set, &cur_set);
4965
            ret = target_set;
4966
        }
4967
        break;
4968
#endif
4969
#ifdef TARGET_NR_ssetmask /* not on alpha */
4970
    case TARGET_NR_ssetmask:
4971
        {
4972
            sigset_t set, oset, cur_set;
4973
            abi_ulong target_set = arg1;
4974
            sigprocmask(0, NULL, &cur_set);
4975
            target_to_host_old_sigset(&set, &target_set);
4976
            sigorset(&set, &set, &cur_set);
4977
            sigprocmask(SIG_SETMASK, &set, &oset);
4978
            host_to_target_old_sigset(&target_set, &oset);
4979
            ret = target_set;
4980
        }
4981
        break;
4982
#endif
4983
#ifdef TARGET_NR_sigprocmask
4984
    case TARGET_NR_sigprocmask:
4985
        {
4986
#if defined(TARGET_ALPHA)
4987
            sigset_t set, oldset;
4988
            abi_ulong mask;
4989
            int how;
4990

    
4991
            switch (arg1) {
4992
            case TARGET_SIG_BLOCK:
4993
                how = SIG_BLOCK;
4994
                break;
4995
            case TARGET_SIG_UNBLOCK:
4996
                how = SIG_UNBLOCK;
4997
                break;
4998
            case TARGET_SIG_SETMASK:
4999
                how = SIG_SETMASK;
5000
                break;
5001
            default:
5002
                ret = -TARGET_EINVAL;
5003
                goto fail;
5004
            }
5005
            mask = arg2;
5006
            target_to_host_old_sigset(&set, &mask);
5007

    
5008
            ret = get_errno(sigprocmask(how, &set, &oldset));
5009

    
5010
            if (!is_error(ret)) {
5011
                host_to_target_old_sigset(&mask, &oldset);
5012
                ret = mask;
5013
                ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
5014
            }
5015
#else
5016
            sigset_t set, oldset, *set_ptr;
5017
            int how;
5018

    
5019
            if (arg2) {
5020
                switch (arg1) {
5021
                case TARGET_SIG_BLOCK:
5022
                    how = SIG_BLOCK;
5023
                    break;
5024
                case TARGET_SIG_UNBLOCK:
5025
                    how = SIG_UNBLOCK;
5026
                    break;
5027
                case TARGET_SIG_SETMASK:
5028
                    how = SIG_SETMASK;
5029
                    break;
5030
                default:
5031
                    ret = -TARGET_EINVAL;
5032
                    goto fail;
5033
                }
5034
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5035
                    goto efault;
5036
                target_to_host_old_sigset(&set, p);
5037
                unlock_user(p, arg2, 0);
5038
                set_ptr = &set;
5039
            } else {
5040
                how = 0;
5041
                set_ptr = NULL;
5042
            }
5043
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5044
            if (!is_error(ret) && arg3) {
5045
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5046
                    goto efault;
5047
                host_to_target_old_sigset(p, &oldset);
5048
                unlock_user(p, arg3, sizeof(target_sigset_t));
5049
            }
5050
#endif
5051
        }
5052
        break;
5053
#endif
5054
    case TARGET_NR_rt_sigprocmask:
5055
        {
5056
            int how = arg1;
5057
            sigset_t set, oldset, *set_ptr;
5058

    
5059
            if (arg2) {
5060
                switch(how) {
5061
                case TARGET_SIG_BLOCK:
5062
                    how = SIG_BLOCK;
5063
                    break;
5064
                case TARGET_SIG_UNBLOCK:
5065
                    how = SIG_UNBLOCK;
5066
                    break;
5067
                case TARGET_SIG_SETMASK:
5068
                    how = SIG_SETMASK;
5069
                    break;
5070
                default:
5071
                    ret = -TARGET_EINVAL;
5072
                    goto fail;
5073
                }
5074
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5075
                    goto efault;
5076
                target_to_host_sigset(&set, p);
5077
                unlock_user(p, arg2, 0);
5078
                set_ptr = &set;
5079
            } else {
5080
                how = 0;
5081
                set_ptr = NULL;
5082
            }
5083
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5084
            if (!is_error(ret) && arg3) {
5085
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5086
                    goto efault;
5087
                host_to_target_sigset(p, &oldset);
5088
                unlock_user(p, arg3, sizeof(target_sigset_t));
5089
            }
5090
        }
5091
        break;
5092
#ifdef TARGET_NR_sigpending
5093
    case TARGET_NR_sigpending:
5094
        {
5095
            sigset_t set;
5096
            ret = get_errno(sigpending(&set));
5097
            if (!is_error(ret)) {
5098
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5099
                    goto efault;
5100
                host_to_target_old_sigset(p, &set);
5101
                unlock_user(p, arg1, sizeof(target_sigset_t));
5102
            }
5103
        }
5104
        break;
5105
#endif
5106
    case TARGET_NR_rt_sigpending:
5107
        {
5108
            sigset_t set;
5109
            ret = get_errno(sigpending(&set));
5110
            if (!is_error(ret)) {
5111
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5112
                    goto efault;
5113
                host_to_target_sigset(p, &set);
5114
                unlock_user(p, arg1, sizeof(target_sigset_t));
5115
            }
5116
        }
5117
        break;
5118
#ifdef TARGET_NR_sigsuspend
5119
    case TARGET_NR_sigsuspend:
5120
        {
5121
            sigset_t set;
5122
#if defined(TARGET_ALPHA)
5123
            abi_ulong mask = arg1;
5124
            target_to_host_old_sigset(&set, &mask);
5125
#else
5126
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5127
                goto efault;
5128
            target_to_host_old_sigset(&set, p);
5129
            unlock_user(p, arg1, 0);
5130
#endif
5131
            ret = get_errno(sigsuspend(&set));
5132
        }
5133
        break;
5134
#endif
5135
    case TARGET_NR_rt_sigsuspend:
5136
        {
5137
            sigset_t set;
5138
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5139
                goto efault;
5140
            target_to_host_sigset(&set, p);
5141
            unlock_user(p, arg1, 0);
5142
            ret = get_errno(sigsuspend(&set));
5143
        }
5144
        break;
5145
    case TARGET_NR_rt_sigtimedwait:
5146
        {
5147
            sigset_t set;
5148
            struct timespec uts, *puts;
5149
            siginfo_t uinfo;
5150

    
5151
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5152
                goto efault;
5153
            target_to_host_sigset(&set, p);
5154
            unlock_user(p, arg1, 0);
5155
            if (arg3) {
5156
                puts = &uts;
5157
                target_to_host_timespec(puts, arg3);
5158
            } else {
5159
                puts = NULL;
5160
            }
5161
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5162
            if (!is_error(ret) && arg2) {
5163
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5164
                    goto efault;
5165
                host_to_target_siginfo(p, &uinfo);
5166
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5167
            }
5168
        }
5169
        break;
5170
    case TARGET_NR_rt_sigqueueinfo:
5171
        {
5172
            siginfo_t uinfo;
5173
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5174
                goto efault;
5175
            target_to_host_siginfo(&uinfo, p);
5176
            unlock_user(p, arg1, 0);
5177
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5178
        }
5179
        break;
5180
#ifdef TARGET_NR_sigreturn
5181
    case TARGET_NR_sigreturn:
5182
        /* NOTE: ret is eax, so not transcoding must be done */
5183
        ret = do_sigreturn(cpu_env);
5184
        break;
5185
#endif
5186
    case TARGET_NR_rt_sigreturn:
5187
        /* NOTE: ret is eax, so not transcoding must be done */
5188
        ret = do_rt_sigreturn(cpu_env);
5189
        break;
5190
    case TARGET_NR_sethostname:
5191
        if (!(p = lock_user_string(arg1)))
5192
            goto efault;
5193
        ret = get_errno(sethostname(p, arg2));
5194
        unlock_user(p, arg1, 0);
5195
        break;
5196
    case TARGET_NR_setrlimit:
5197
        {
5198
            int resource = arg1;
5199
            struct target_rlimit *target_rlim;
5200
            struct rlimit rlim;
5201
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5202
                goto efault;
5203
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
5204
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
5205
            unlock_user_struct(target_rlim, arg2, 0);
5206
            ret = get_errno(setrlimit(resource, &rlim));
5207
        }
5208
        break;
5209
    case TARGET_NR_getrlimit:
5210
        {
5211
            int resource = arg1;
5212
            struct target_rlimit *target_rlim;
5213
            struct rlimit rlim;
5214

    
5215
            ret = get_errno(getrlimit(resource, &rlim));
5216
            if (!is_error(ret)) {
5217
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5218
                    goto efault;
5219
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
5220
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
5221
                unlock_user_struct(target_rlim, arg2, 1);
5222
            }
5223
        }
5224
        break;
5225
    case TARGET_NR_getrusage:
5226
        {
5227
            struct rusage rusage;
5228
            ret = get_errno(getrusage(arg1, &rusage));
5229
            if (!is_error(ret)) {
5230
                host_to_target_rusage(arg2, &rusage);
5231
            }
5232
        }
5233
        break;
5234
    case TARGET_NR_gettimeofday:
5235
        {
5236
            struct timeval tv;
5237
            ret = get_errno(gettimeofday(&tv, NULL));
5238
            if (!is_error(ret)) {
5239
                if (copy_to_user_timeval(arg1, &tv))
5240
                    goto efault;
5241
            }
5242
        }
5243
        break;
5244
    case TARGET_NR_settimeofday:
5245
        {
5246
            struct timeval tv;
5247
            if (copy_from_user_timeval(&tv, arg1))
5248
                goto efault;
5249
            ret = get_errno(settimeofday(&tv, NULL));
5250
        }
5251
        break;
5252
#ifdef TARGET_NR_select
5253
    case TARGET_NR_select:
5254
        {
5255
            struct target_sel_arg_struct *sel;
5256
            abi_ulong inp, outp, exp, tvp;
5257
            long nsel;
5258

    
5259
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5260
                goto efault;
5261
            nsel = tswapl(sel->n);
5262
            inp = tswapl(sel->inp);
5263
            outp = tswapl(sel->outp);
5264
            exp = tswapl(sel->exp);
5265
            tvp = tswapl(sel->tvp);
5266
            unlock_user_struct(sel, arg1, 0);
5267
            ret = do_select(nsel, inp, outp, exp, tvp);
5268
        }
5269
        break;
5270
#endif
5271
#ifdef TARGET_NR_pselect6
5272
    case TARGET_NR_pselect6:
5273
            goto unimplemented_nowarn;
5274
#endif
5275
    case TARGET_NR_symlink:
5276
        {
5277
            void *p2;
5278
            p = lock_user_string(arg1);
5279
            p2 = lock_user_string(arg2);
5280
            if (!p || !p2)
5281
                ret = -TARGET_EFAULT;
5282
            else
5283
                ret = get_errno(symlink(p, p2));
5284
            unlock_user(p2, arg2, 0);
5285
            unlock_user(p, arg1, 0);
5286
        }
5287
        break;
5288
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5289
    case TARGET_NR_symlinkat:
5290
        {
5291
            void *p2;
5292
            p  = lock_user_string(arg1);
5293
            p2 = lock_user_string(arg3);
5294
            if (!p || !p2)
5295
                ret = -TARGET_EFAULT;
5296
            else
5297
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5298
            unlock_user(p2, arg3, 0);
5299
            unlock_user(p, arg1, 0);
5300
        }
5301
        break;
5302
#endif
5303
#ifdef TARGET_NR_oldlstat
5304
    case TARGET_NR_oldlstat:
5305
        goto unimplemented;
5306
#endif
5307
    case TARGET_NR_readlink:
5308
        {
5309
            void *p2, *temp;
5310
            p = lock_user_string(arg1);
5311
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5312
            if (!p || !p2)
5313
                ret = -TARGET_EFAULT;
5314
            else {
5315
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5316
                    char real[PATH_MAX];
5317
                    temp = realpath(exec_path,real);
5318
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5319
                    snprintf((char *)p2, arg3, "%s", real);
5320
                    }
5321
                else
5322
                    ret = get_errno(readlink(path(p), p2, arg3));
5323
            }
5324
            unlock_user(p2, arg2, ret);
5325
            unlock_user(p, arg1, 0);
5326
        }
5327
        break;
5328
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5329
    case TARGET_NR_readlinkat:
5330
        {
5331
            void *p2;
5332
            p  = lock_user_string(arg2);
5333
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5334
            if (!p || !p2)
5335
                ret = -TARGET_EFAULT;
5336
            else
5337
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5338
            unlock_user(p2, arg3, ret);
5339
            unlock_user(p, arg2, 0);
5340
        }
5341
        break;
5342
#endif
5343
#ifdef TARGET_NR_uselib
5344
    case TARGET_NR_uselib:
5345
        goto unimplemented;
5346
#endif
5347
#ifdef TARGET_NR_swapon
5348
    case TARGET_NR_swapon:
5349
        if (!(p = lock_user_string(arg1)))
5350
            goto efault;
5351
        ret = get_errno(swapon(p, arg2));
5352
        unlock_user(p, arg1, 0);
5353
        break;
5354
#endif
5355
    case TARGET_NR_reboot:
5356
        goto unimplemented;
5357
#ifdef TARGET_NR_readdir
5358
    case TARGET_NR_readdir:
5359
        goto unimplemented;
5360
#endif
5361
#ifdef TARGET_NR_mmap
5362
    case TARGET_NR_mmap:
5363
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5364
        {
5365
            abi_ulong *v;
5366
            abi_ulong v1, v2, v3, v4, v5, v6;
5367
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5368
                goto efault;
5369
            v1 = tswapl(v[0]);
5370
            v2 = tswapl(v[1]);
5371
            v3 = tswapl(v[2]);
5372
            v4 = tswapl(v[3]);
5373
            v5 = tswapl(v[4]);
5374
            v6 = tswapl(v[5]);
5375
            unlock_user(v, arg1, 0);
5376
            ret = get_errno(target_mmap(v1, v2, v3,
5377
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5378
                                        v5, v6));
5379
        }
5380
#else
5381
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5382
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5383
                                    arg5,
5384
                                    arg6));
5385
#endif
5386
        break;
5387
#endif
5388
#ifdef TARGET_NR_mmap2
5389
    case TARGET_NR_mmap2:
5390
#ifndef MMAP_SHIFT
5391
#define MMAP_SHIFT 12
5392
#endif
5393
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5394
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5395
                                    arg5,
5396
                                    arg6 << MMAP_SHIFT));
5397
        break;
5398
#endif
5399
    case TARGET_NR_munmap:
5400
        ret = get_errno(target_munmap(arg1, arg2));
5401
        break;
5402
    case TARGET_NR_mprotect:
5403
        {
5404
            TaskState *ts = ((CPUState *)cpu_env)->opaque;
5405
            /* Special hack to detect libc making the stack executable.  */
5406
            if ((arg3 & PROT_GROWSDOWN)
5407
                && arg1 >= ts->info->stack_limit
5408
                && arg1 <= ts->info->start_stack) {
5409
                arg3 &= ~PROT_GROWSDOWN;
5410
                arg2 = arg2 + arg1 - ts->info->stack_limit;
5411
                arg1 = ts->info->stack_limit;
5412
            }
5413
        }
5414
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5415
        break;
5416
#ifdef TARGET_NR_mremap
5417
    case TARGET_NR_mremap:
5418
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5419
        break;
5420
#endif
5421
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5422
#ifdef TARGET_NR_msync
5423
    case TARGET_NR_msync:
5424
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5425
        break;
5426
#endif
5427
#ifdef TARGET_NR_mlock
5428
    case TARGET_NR_mlock:
5429
        ret = get_errno(mlock(g2h(arg1), arg2));
5430
        break;
5431
#endif
5432
#ifdef TARGET_NR_munlock
5433
    case TARGET_NR_munlock:
5434
        ret = get_errno(munlock(g2h(arg1), arg2));
5435
        break;
5436
#endif
5437
#ifdef TARGET_NR_mlockall
5438
    case TARGET_NR_mlockall:
5439
        ret = get_errno(mlockall(arg1));
5440
        break;
5441
#endif
5442
#ifdef TARGET_NR_munlockall
5443
    case TARGET_NR_munlockall:
5444
        ret = get_errno(munlockall());
5445
        break;
5446
#endif
5447
    case TARGET_NR_truncate:
5448
        if (!(p = lock_user_string(arg1)))
5449
            goto efault;
5450
        ret = get_errno(truncate(p, arg2));
5451
        unlock_user(p, arg1, 0);
5452
        break;
5453
    case TARGET_NR_ftruncate:
5454
        ret = get_errno(ftruncate(arg1, arg2));
5455
        break;
5456
    case TARGET_NR_fchmod:
5457
        ret = get_errno(fchmod(arg1, arg2));
5458
        break;
5459
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5460
    case TARGET_NR_fchmodat:
5461
        if (!(p = lock_user_string(arg2)))
5462
            goto efault;
5463
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5464
        unlock_user(p, arg2, 0);
5465
        break;
5466
#endif
5467
    case TARGET_NR_getpriority:
5468
        /* libc does special remapping of the return value of
5469
         * sys_getpriority() so it's just easiest to call
5470
         * sys_getpriority() directly rather than through libc. */
5471
        ret = get_errno(sys_getpriority(arg1, arg2));
5472
        break;
5473
    case TARGET_NR_setpriority:
5474
        ret = get_errno(setpriority(arg1, arg2, arg3));
5475
        break;
5476
#ifdef TARGET_NR_profil
5477
    case TARGET_NR_profil:
5478
        goto unimplemented;
5479
#endif
5480
    case TARGET_NR_statfs:
5481
        if (!(p = lock_user_string(arg1)))
5482
            goto efault;
5483
        ret = get_errno(statfs(path(p), &stfs));
5484
        unlock_user(p, arg1, 0);
5485
    convert_statfs:
5486
        if (!is_error(ret)) {
5487
            struct target_statfs *target_stfs;
5488

    
5489
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5490
                goto efault;
5491
            __put_user(stfs.f_type, &target_stfs->f_type);
5492
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5493
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5494
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5495
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5496
            __put_user(stfs.f_files, &target_stfs->f_files);
5497
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5498
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5499
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5500
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5501
            unlock_user_struct(target_stfs, arg2, 1);
5502
        }
5503
        break;
5504
    case TARGET_NR_fstatfs:
5505
        ret = get_errno(fstatfs(arg1, &stfs));
5506
        goto convert_statfs;
5507
#ifdef TARGET_NR_statfs64
5508
    case TARGET_NR_statfs64:
5509
        if (!(p = lock_user_string(arg1)))
5510
            goto efault;
5511
        ret = get_errno(statfs(path(p), &stfs));
5512
        unlock_user(p, arg1, 0);
5513
    convert_statfs64:
5514
        if (!is_error(ret)) {
5515
            struct target_statfs64 *target_stfs;
5516

    
5517
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5518
                goto efault;
5519
            __put_user(stfs.f_type, &target_stfs->f_type);
5520
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5521
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5522
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5523
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5524
            __put_user(stfs.f_files, &target_stfs->f_files);
5525
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5526
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5527
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5528
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5529
            unlock_user_struct(target_stfs, arg3, 1);
5530
        }
5531
        break;
5532
    case TARGET_NR_fstatfs64:
5533
        ret = get_errno(fstatfs(arg1, &stfs));
5534
        goto convert_statfs64;
5535
#endif
5536
#ifdef TARGET_NR_ioperm
5537
    case TARGET_NR_ioperm:
5538
        goto unimplemented;
5539
#endif
5540
#ifdef TARGET_NR_socketcall
5541
    case TARGET_NR_socketcall:
5542
        ret = do_socketcall(arg1, arg2);
5543
        break;
5544
#endif
5545
#ifdef TARGET_NR_accept
5546
    case TARGET_NR_accept:
5547
        ret = do_accept(arg1, arg2, arg3);
5548
        break;
5549
#endif
5550
#ifdef TARGET_NR_bind
5551
    case TARGET_NR_bind:
5552
        ret = do_bind(arg1, arg2, arg3);
5553
        break;
5554
#endif
5555
#ifdef TARGET_NR_connect
5556
    case TARGET_NR_connect:
5557
        ret = do_connect(arg1, arg2, arg3);
5558
        break;
5559
#endif
5560
#ifdef TARGET_NR_getpeername
5561
    case TARGET_NR_getpeername:
5562
        ret = do_getpeername(arg1, arg2, arg3);
5563
        break;
5564
#endif
5565
#ifdef TARGET_NR_getsockname
5566
    case TARGET_NR_getsockname:
5567
        ret = do_getsockname(arg1, arg2, arg3);
5568
        break;
5569
#endif
5570
#ifdef TARGET_NR_getsockopt
5571
    case TARGET_NR_getsockopt:
5572
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5573
        break;
5574
#endif
5575
#ifdef TARGET_NR_listen
5576
    case TARGET_NR_listen:
5577
        ret = get_errno(listen(arg1, arg2));
5578
        break;
5579
#endif
5580
#ifdef TARGET_NR_recv
5581
    case TARGET_NR_recv:
5582
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5583
        break;
5584
#endif
5585
#ifdef TARGET_NR_recvfrom
5586
    case TARGET_NR_recvfrom:
5587
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5588
        break;
5589
#endif
5590
#ifdef TARGET_NR_recvmsg
5591
    case TARGET_NR_recvmsg:
5592
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5593
        break;
5594
#endif
5595
#ifdef TARGET_NR_send
5596
    case TARGET_NR_send:
5597
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5598
        break;
5599
#endif
5600
#ifdef TARGET_NR_sendmsg
5601
    case TARGET_NR_sendmsg:
5602
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5603
        break;
5604
#endif
5605
#ifdef TARGET_NR_sendto
5606
    case TARGET_NR_sendto:
5607
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5608
        break;
5609
#endif
5610
#ifdef TARGET_NR_shutdown
5611
    case TARGET_NR_shutdown:
5612
        ret = get_errno(shutdown(arg1, arg2));
5613
        break;
5614
#endif
5615
#ifdef TARGET_NR_socket
5616
    case TARGET_NR_socket:
5617
        ret = do_socket(arg1, arg2, arg3);
5618
        break;
5619
#endif
5620
#ifdef TARGET_NR_socketpair
5621
    case TARGET_NR_socketpair:
5622
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5623
        break;
5624
#endif
5625
#ifdef TARGET_NR_setsockopt
5626
    case TARGET_NR_setsockopt:
5627
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5628
        break;
5629
#endif
5630

    
5631
    case TARGET_NR_syslog:
5632
        if (!(p = lock_user_string(arg2)))
5633
            goto efault;
5634
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5635
        unlock_user(p, arg2, 0);
5636
        break;
5637

    
5638
    case TARGET_NR_setitimer:
5639
        {
5640
            struct itimerval value, ovalue, *pvalue;
5641

    
5642
            if (arg2) {
5643
                pvalue = &value;
5644
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5645
                    || copy_from_user_timeval(&pvalue->it_value,
5646
                                              arg2 + sizeof(struct target_timeval)))
5647
                    goto efault;
5648
            } else {
5649
                pvalue = NULL;
5650
            }
5651
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5652
            if (!is_error(ret) && arg3) {
5653
                if (copy_to_user_timeval(arg3,
5654
                                         &ovalue.it_interval)
5655
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5656
                                            &ovalue.it_value))
5657
                    goto efault;
5658
            }
5659
        }
5660
        break;
5661
    case TARGET_NR_getitimer:
5662
        {
5663
            struct itimerval value;
5664

    
5665
            ret = get_errno(getitimer(arg1, &value));
5666
            if (!is_error(ret) && arg2) {
5667
                if (copy_to_user_timeval(arg2,
5668
                                         &value.it_interval)
5669
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5670
                                            &value.it_value))
5671
                    goto efault;
5672
            }
5673
        }
5674
        break;
5675
    case TARGET_NR_stat:
5676
        if (!(p = lock_user_string(arg1)))
5677
            goto efault;
5678
        ret = get_errno(stat(path(p), &st));
5679
        unlock_user(p, arg1, 0);
5680
        goto do_stat;
5681
    case TARGET_NR_lstat:
5682
        if (!(p = lock_user_string(arg1)))
5683
            goto efault;
5684
        ret = get_errno(lstat(path(p), &st));
5685
        unlock_user(p, arg1, 0);
5686
        goto do_stat;
5687
    case TARGET_NR_fstat:
5688
        {
5689
            ret = get_errno(fstat(arg1, &st));
5690
        do_stat:
5691
            if (!is_error(ret)) {
5692
                struct target_stat *target_st;
5693

    
5694
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5695
                    goto efault;
5696
                memset(target_st, 0, sizeof(*target_st));
5697
                __put_user(st.st_dev, &target_st->st_dev);
5698
                __put_user(st.st_ino, &target_st->st_ino);
5699
                __put_user(st.st_mode, &target_st->st_mode);
5700
                __put_user(st.st_uid, &target_st->st_uid);
5701
                __put_user(st.st_gid, &target_st->st_gid);
5702
                __put_user(st.st_nlink, &target_st->st_nlink);
5703
                __put_user(st.st_rdev, &target_st->st_rdev);
5704
                __put_user(st.st_size, &target_st->st_size);
5705
                __put_user(st.st_blksize, &target_st->st_blksize);
5706
                __put_user(st.st_blocks, &target_st->st_blocks);
5707
                __put_user(st.st_atime, &target_st->target_st_atime);
5708
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5709
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5710
                unlock_user_struct(target_st, arg2, 1);
5711
            }
5712
        }
5713
        break;
5714
#ifdef TARGET_NR_olduname
5715
    case TARGET_NR_olduname:
5716
        goto unimplemented;
5717
#endif
5718
#ifdef TARGET_NR_iopl
5719
    case TARGET_NR_iopl:
5720
        goto unimplemented;
5721
#endif
5722
    case TARGET_NR_vhangup:
5723
        ret = get_errno(vhangup());
5724
        break;
5725
#ifdef TARGET_NR_idle
5726
    case TARGET_NR_idle:
5727
        goto unimplemented;
5728
#endif
5729
#ifdef TARGET_NR_syscall
5730
    case TARGET_NR_syscall:
5731
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5732
            break;
5733
#endif
5734
    case TARGET_NR_wait4:
5735
        {
5736
            int status;
5737
            abi_long status_ptr = arg2;
5738
            struct rusage rusage, *rusage_ptr;
5739
            abi_ulong target_rusage = arg4;
5740
            if (target_rusage)
5741
                rusage_ptr = &rusage;
5742
            else
5743
                rusage_ptr = NULL;
5744
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5745
            if (!is_error(ret)) {
5746
                if (status_ptr) {
5747
                    status = host_to_target_waitstatus(status);
5748
                    if (put_user_s32(status, status_ptr))
5749
                        goto efault;
5750
                }
5751
                if (target_rusage)
5752
                    host_to_target_rusage(target_rusage, &rusage);
5753
            }
5754
        }
5755
        break;
5756
#ifdef TARGET_NR_swapoff
5757
    case TARGET_NR_swapoff:
5758
        if (!(p = lock_user_string(arg1)))
5759
            goto efault;
5760
        ret = get_errno(swapoff(p));
5761
        unlock_user(p, arg1, 0);
5762
        break;
5763
#endif
5764
    case TARGET_NR_sysinfo:
5765
        {
5766
            struct target_sysinfo *target_value;
5767
            struct sysinfo value;
5768
            ret = get_errno(sysinfo(&value));
5769
            if (!is_error(ret) && arg1)
5770
            {
5771
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5772
                    goto efault;
5773
                __put_user(value.uptime, &target_value->uptime);
5774
                __put_user(value.loads[0], &target_value->loads[0]);
5775
                __put_user(value.loads[1], &target_value->loads[1]);
5776
                __put_user(value.loads[2], &target_value->loads[2]);
5777
                __put_user(value.totalram, &target_value->totalram);
5778
                __put_user(value.freeram, &target_value->freeram);
5779
                __put_user(value.sharedram, &target_value->sharedram);
5780
                __put_user(value.bufferram, &target_value->bufferram);
5781
                __put_user(value.totalswap, &target_value->totalswap);
5782
                __put_user(value.freeswap, &target_value->freeswap);
5783
                __put_user(value.procs, &target_value->procs);
5784
                __put_user(value.totalhigh, &target_value->totalhigh);
5785
                __put_user(value.freehigh, &target_value->freehigh);
5786
                __put_user(value.mem_unit, &target_value->mem_unit);
5787
                unlock_user_struct(target_value, arg1, 1);
5788
            }
5789
        }
5790
        break;
5791
#ifdef TARGET_NR_ipc
5792
    case TARGET_NR_ipc:
5793
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5794
        break;
5795
#endif
5796
#ifdef TARGET_NR_semget
5797
    case TARGET_NR_semget:
5798
        ret = get_errno(semget(arg1, arg2, arg3));
5799
        break;
5800
#endif
5801
#ifdef TARGET_NR_semop
5802
    case TARGET_NR_semop:
5803
        ret = get_errno(do_semop(arg1, arg2, arg3));
5804
        break;
5805
#endif
5806
#ifdef TARGET_NR_semctl
5807
    case TARGET_NR_semctl:
5808
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5809
        break;
5810
#endif
5811
#ifdef TARGET_NR_msgctl
5812
    case TARGET_NR_msgctl:
5813
        ret = do_msgctl(arg1, arg2, arg3);
5814
        break;
5815
#endif
5816
#ifdef TARGET_NR_msgget
5817
    case TARGET_NR_msgget:
5818
        ret = get_errno(msgget(arg1, arg2));
5819
        break;
5820
#endif
5821
#ifdef TARGET_NR_msgrcv
5822
    case TARGET_NR_msgrcv:
5823
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5824
        break;
5825
#endif
5826
#ifdef TARGET_NR_msgsnd
5827
    case TARGET_NR_msgsnd:
5828
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5829
        break;
5830
#endif
5831
#ifdef TARGET_NR_shmget
5832
    case TARGET_NR_shmget:
5833
        ret = get_errno(shmget(arg1, arg2, arg3));
5834
        break;
5835
#endif
5836
#ifdef TARGET_NR_shmctl
5837
    case TARGET_NR_shmctl:
5838
        ret = do_shmctl(arg1, arg2, arg3);
5839
        break;
5840
#endif
5841
#ifdef TARGET_NR_shmat
5842
    case TARGET_NR_shmat:
5843
        ret = do_shmat(arg1, arg2, arg3);
5844
        break;
5845
#endif
5846
#ifdef TARGET_NR_shmdt
5847
    case TARGET_NR_shmdt:
5848
        ret = do_shmdt(arg1);
5849
        break;
5850
#endif
5851
    case TARGET_NR_fsync:
5852
        ret = get_errno(fsync(arg1));
5853
        break;
5854
    case TARGET_NR_clone:
5855
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
5856
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5857
#elif defined(TARGET_CRIS)
5858
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5859
#else
5860
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5861
#endif
5862
        break;
5863
#ifdef __NR_exit_group
5864
        /* new thread calls */
5865
    case TARGET_NR_exit_group:
5866
#ifdef TARGET_GPROF
5867
        _mcleanup();
5868
#endif
5869
        gdb_exit(cpu_env, arg1);
5870
        ret = get_errno(exit_group(arg1));
5871
        break;
5872
#endif
5873
    case TARGET_NR_setdomainname:
5874
        if (!(p = lock_user_string(arg1)))
5875
            goto efault;
5876
        ret = get_errno(setdomainname(p, arg2));
5877
        unlock_user(p, arg1, 0);
5878
        break;
5879
    case TARGET_NR_uname:
5880
        /* no need to transcode because we use the linux syscall */
5881
        {
5882
            struct new_utsname * buf;
5883

    
5884
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5885
                goto efault;
5886
            ret = get_errno(sys_uname(buf));
5887
            if (!is_error(ret)) {
5888
                /* Overrite the native machine name with whatever is being
5889
                   emulated. */
5890
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
5891
                /* Allow the user to override the reported release.  */
5892
                if (qemu_uname_release && *qemu_uname_release)
5893
                  strcpy (buf->release, qemu_uname_release);
5894
            }
5895
            unlock_user_struct(buf, arg1, 1);
5896
        }
5897
        break;
5898
#ifdef TARGET_I386
5899
    case TARGET_NR_modify_ldt:
5900
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5901
        break;
5902
#if !defined(TARGET_X86_64)
5903
    case TARGET_NR_vm86old:
5904
        goto unimplemented;
5905
    case TARGET_NR_vm86:
5906
        ret = do_vm86(cpu_env, arg1, arg2);
5907
        break;
5908
#endif
5909
#endif
5910
    case TARGET_NR_adjtimex:
5911
        goto unimplemented;
5912
#ifdef TARGET_NR_create_module
5913
    case TARGET_NR_create_module:
5914
#endif
5915
    case TARGET_NR_init_module:
5916
    case TARGET_NR_delete_module:
5917
#ifdef TARGET_NR_get_kernel_syms
5918
    case TARGET_NR_get_kernel_syms:
5919
#endif
5920
        goto unimplemented;
5921
    case TARGET_NR_quotactl:
5922
        goto unimplemented;
5923
    case TARGET_NR_getpgid:
5924
        ret = get_errno(getpgid(arg1));
5925
        break;
5926
    case TARGET_NR_fchdir:
5927
        ret = get_errno(fchdir(arg1));
5928
        break;
5929
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5930
    case TARGET_NR_bdflush:
5931
        goto unimplemented;
5932
#endif
5933
#ifdef TARGET_NR_sysfs
5934
    case TARGET_NR_sysfs:
5935
        goto unimplemented;
5936
#endif
5937
    case TARGET_NR_personality:
5938
        ret = get_errno(personality(arg1));
5939
        break;
5940
#ifdef TARGET_NR_afs_syscall
5941
    case TARGET_NR_afs_syscall:
5942
        goto unimplemented;
5943
#endif
5944
#ifdef TARGET_NR__llseek /* Not on alpha */
5945
    case TARGET_NR__llseek:
5946
        {
5947
#if !defined(__NR_llseek)
5948
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5949
            if (put_user_s64(ret, arg4))
5950
                goto efault;
5951
#else
5952
            int64_t res;
5953
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5954
            if (put_user_s64(res, arg4))
5955
                goto efault;
5956
#endif
5957
        }
5958
        break;
5959
#endif
5960
    case TARGET_NR_getdents:
5961
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5962
        {
5963
            struct target_dirent *target_dirp;
5964
            struct linux_dirent *dirp;
5965
            abi_long count = arg3;
5966

    
5967
            dirp = malloc(count);
5968
            if (!dirp) {
5969
                ret = -TARGET_ENOMEM;
5970
                goto fail;
5971
            }
5972

    
5973
            ret = get_errno(sys_getdents(arg1, dirp, count));
5974
            if (!is_error(ret)) {
5975
                struct linux_dirent *de;
5976
                struct target_dirent *tde;
5977
                int len = ret;
5978
                int reclen, treclen;
5979
                int count1, tnamelen;
5980

    
5981
                count1 = 0;
5982
                de = dirp;
5983
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5984
                    goto efault;
5985
                tde = target_dirp;
5986
                while (len > 0) {
5987
                    reclen = de->d_reclen;
5988
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5989
                    tde->d_reclen = tswap16(treclen);
5990
                    tde->d_ino = tswapl(de->d_ino);
5991
                    tde->d_off = tswapl(de->d_off);
5992
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5993
                    if (tnamelen > 256)
5994
                        tnamelen = 256;
5995
                    /* XXX: may not be correct */
5996
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5997
                    de = (struct linux_dirent *)((char *)de + reclen);
5998
                    len -= reclen;
5999
                    tde = (struct target_dirent *)((char *)tde + treclen);
6000
                    count1 += treclen;
6001
                }
6002
                ret = count1;
6003
                unlock_user(target_dirp, arg2, ret);
6004
            }
6005
            free(dirp);
6006
        }
6007
#else
6008
        {
6009
            struct linux_dirent *dirp;
6010
            abi_long count = arg3;
6011

    
6012
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6013
                goto efault;
6014
            ret = get_errno(sys_getdents(arg1, dirp, count));
6015
            if (!is_error(ret)) {
6016
                struct linux_dirent *de;
6017
                int len = ret;
6018
                int reclen;
6019
                de = dirp;
6020
                while (len > 0) {
6021
                    reclen = de->d_reclen;
6022
                    if (reclen > len)
6023
                        break;
6024
                    de->d_reclen = tswap16(reclen);
6025
                    tswapls(&de->d_ino);
6026
                    tswapls(&de->d_off);
6027
                    de = (struct linux_dirent *)((char *)de + reclen);
6028
                    len -= reclen;
6029
                }
6030
            }
6031
            unlock_user(dirp, arg2, ret);
6032
        }
6033
#endif
6034
        break;
6035
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
6036
    case TARGET_NR_getdents64:
6037
        {
6038
            struct linux_dirent64 *dirp;
6039
            abi_long count = arg3;
6040
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6041
                goto efault;
6042
            ret = get_errno(sys_getdents64(arg1, dirp, count));
6043
            if (!is_error(ret)) {
6044
                struct linux_dirent64 *de;
6045
                int len = ret;
6046
                int reclen;
6047
                de = dirp;
6048
                while (len > 0) {
6049
                    reclen = de->d_reclen;
6050
                    if (reclen > len)
6051
                        break;
6052
                    de->d_reclen = tswap16(reclen);
6053
                    tswap64s((uint64_t *)&de->d_ino);
6054
                    tswap64s((uint64_t *)&de->d_off);
6055
                    de = (struct linux_dirent64 *)((char *)de + reclen);
6056
                    len -= reclen;
6057
                }
6058
            }
6059
            unlock_user(dirp, arg2, ret);
6060
        }
6061
        break;
6062
#endif /* TARGET_NR_getdents64 */
6063
#ifdef TARGET_NR__newselect
6064
    case TARGET_NR__newselect:
6065
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6066
        break;
6067
#endif
6068
#ifdef TARGET_NR_poll
6069
    case TARGET_NR_poll:
6070
        {
6071
            struct target_pollfd *target_pfd;
6072
            unsigned int nfds = arg2;
6073
            int timeout = arg3;
6074
            struct pollfd *pfd;
6075
            unsigned int i;
6076

    
6077
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
6078
            if (!target_pfd)
6079
                goto efault;
6080
            pfd = alloca(sizeof(struct pollfd) * nfds);
6081
            for(i = 0; i < nfds; i++) {
6082
                pfd[i].fd = tswap32(target_pfd[i].fd);
6083
                pfd[i].events = tswap16(target_pfd[i].events);
6084
            }
6085
            ret = get_errno(poll(pfd, nfds, timeout));
6086
            if (!is_error(ret)) {
6087
                for(i = 0; i < nfds; i++) {
6088
                    target_pfd[i].revents = tswap16(pfd[i].revents);
6089
                }
6090
                ret += nfds * (sizeof(struct target_pollfd)
6091
                               - sizeof(struct pollfd));
6092
            }
6093
            unlock_user(target_pfd, arg1, ret);
6094
        }
6095
        break;
6096
#endif
6097
    case TARGET_NR_flock:
6098
        /* NOTE: the flock constant seems to be the same for every
6099
           Linux platform */
6100
        ret = get_errno(flock(arg1, arg2));
6101
        break;
6102
    case TARGET_NR_readv:
6103
        {
6104
            int count = arg3;
6105
            struct iovec *vec;
6106

    
6107
            vec = alloca(count * sizeof(struct iovec));
6108
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6109
                goto efault;
6110
            ret = get_errno(readv(arg1, vec, count));
6111
            unlock_iovec(vec, arg2, count, 1);
6112
        }
6113
        break;
6114
    case TARGET_NR_writev:
6115
        {
6116
            int count = arg3;
6117
            struct iovec *vec;
6118

    
6119
            vec = alloca(count * sizeof(struct iovec));
6120
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6121
                goto efault;
6122
            ret = get_errno(writev(arg1, vec, count));
6123
            unlock_iovec(vec, arg2, count, 0);
6124
        }
6125
        break;
6126
    case TARGET_NR_getsid:
6127
        ret = get_errno(getsid(arg1));
6128
        break;
6129
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6130
    case TARGET_NR_fdatasync:
6131
        ret = get_errno(fdatasync(arg1));
6132
        break;
6133
#endif
6134
    case TARGET_NR__sysctl:
6135
        /* We don't implement this, but ENOTDIR is always a safe
6136
           return value. */
6137
        ret = -TARGET_ENOTDIR;
6138
        break;
6139
    case TARGET_NR_sched_setparam:
6140
        {
6141
            struct sched_param *target_schp;
6142
            struct sched_param schp;
6143

    
6144
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
6145
                goto efault;
6146
            schp.sched_priority = tswap32(target_schp->sched_priority);
6147
            unlock_user_struct(target_schp, arg2, 0);
6148
            ret = get_errno(sched_setparam(arg1, &schp));
6149
        }
6150
        break;
6151
    case TARGET_NR_sched_getparam:
6152
        {
6153
            struct sched_param *target_schp;
6154
            struct sched_param schp;
6155
            ret = get_errno(sched_getparam(arg1, &schp));
6156
            if (!is_error(ret)) {
6157
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
6158
                    goto efault;
6159
                target_schp->sched_priority = tswap32(schp.sched_priority);
6160
                unlock_user_struct(target_schp, arg2, 1);
6161
            }
6162
        }
6163
        break;
6164
    case TARGET_NR_sched_setscheduler:
6165
        {
6166
            struct sched_param *target_schp;
6167
            struct sched_param schp;
6168
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
6169
                goto efault;
6170
            schp.sched_priority = tswap32(target_schp->sched_priority);
6171
            unlock_user_struct(target_schp, arg3, 0);
6172
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
6173
        }
6174
        break;
6175
    case TARGET_NR_sched_getscheduler:
6176
        ret = get_errno(sched_getscheduler(arg1));
6177
        break;
6178
    case TARGET_NR_sched_yield:
6179
        ret = get_errno(sched_yield());
6180
        break;
6181
    case TARGET_NR_sched_get_priority_max:
6182
        ret = get_errno(sched_get_priority_max(arg1));
6183
        break;
6184
    case TARGET_NR_sched_get_priority_min:
6185
        ret = get_errno(sched_get_priority_min(arg1));
6186
        break;
6187
    case TARGET_NR_sched_rr_get_interval:
6188
        {
6189
            struct timespec ts;
6190
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6191
            if (!is_error(ret)) {
6192
                host_to_target_timespec(arg2, &ts);
6193
            }
6194
        }
6195
        break;
6196
    case TARGET_NR_nanosleep:
6197
        {
6198
            struct timespec req, rem;
6199
            target_to_host_timespec(&req, arg1);
6200
            ret = get_errno(nanosleep(&req, &rem));
6201
            if (is_error(ret) && arg2) {
6202
                host_to_target_timespec(arg2, &rem);
6203
            }
6204
        }
6205
        break;
6206
#ifdef TARGET_NR_query_module
6207
    case TARGET_NR_query_module:
6208
        goto unimplemented;
6209
#endif
6210
#ifdef TARGET_NR_nfsservctl
6211
    case TARGET_NR_nfsservctl:
6212
        goto unimplemented;
6213
#endif
6214
    case TARGET_NR_prctl:
6215
        switch (arg1)
6216
            {
6217
            case PR_GET_PDEATHSIG:
6218
                {
6219
                    int deathsig;
6220
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6221
                    if (!is_error(ret) && arg2
6222
                        && put_user_ual(deathsig, arg2))
6223
                        goto efault;
6224
                }
6225
                break;
6226
            default:
6227
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6228
                break;
6229
            }
6230
        break;
6231
#ifdef TARGET_NR_arch_prctl
6232
    case TARGET_NR_arch_prctl:
6233
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6234
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6235
        break;
6236
#else
6237
        goto unimplemented;
6238
#endif
6239
#endif
6240
#ifdef TARGET_NR_pread
6241
    case TARGET_NR_pread:
6242
#ifdef TARGET_ARM
6243
        if (((CPUARMState *)cpu_env)->eabi)
6244
            arg4 = arg5;
6245
#endif
6246
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6247
            goto efault;
6248
        ret = get_errno(pread(arg1, p, arg3, arg4));
6249
        unlock_user(p, arg2, ret);
6250
        break;
6251
    case TARGET_NR_pwrite:
6252
#ifdef TARGET_ARM
6253
        if (((CPUARMState *)cpu_env)->eabi)
6254
            arg4 = arg5;
6255
#endif
6256
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6257
            goto efault;
6258
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6259
        unlock_user(p, arg2, 0);
6260
        break;
6261
#endif
6262
#ifdef TARGET_NR_pread64
6263
    case TARGET_NR_pread64:
6264
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6265
            goto efault;
6266
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6267
        unlock_user(p, arg2, ret);
6268
        break;
6269
    case TARGET_NR_pwrite64:
6270
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6271
            goto efault;
6272
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6273
        unlock_user(p, arg2, 0);
6274
        break;
6275
#endif
6276
    case TARGET_NR_getcwd:
6277
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6278
            goto efault;
6279
        ret = get_errno(sys_getcwd1(p, arg2));
6280
        unlock_user(p, arg1, ret);
6281
        break;
6282
    case TARGET_NR_capget:
6283
        goto unimplemented;
6284
    case TARGET_NR_capset:
6285
        goto unimplemented;
6286
    case TARGET_NR_sigaltstack:
6287
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6288
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
6289
    defined(TARGET_M68K)
6290
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6291
        break;
6292
#else
6293
        goto unimplemented;
6294
#endif
6295
    case TARGET_NR_sendfile:
6296
        goto unimplemented;
6297
#ifdef TARGET_NR_getpmsg
6298
    case TARGET_NR_getpmsg:
6299
        goto unimplemented;
6300
#endif
6301
#ifdef TARGET_NR_putpmsg
6302
    case TARGET_NR_putpmsg:
6303
        goto unimplemented;
6304
#endif
6305
#ifdef TARGET_NR_vfork
6306
    case TARGET_NR_vfork:
6307
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6308
                        0, 0, 0, 0));
6309
        break;
6310
#endif
6311
#ifdef TARGET_NR_ugetrlimit
6312
    case TARGET_NR_ugetrlimit:
6313
    {
6314
        struct rlimit rlim;
6315
        ret = get_errno(getrlimit(arg1, &rlim));
6316
        if (!is_error(ret)) {
6317
            struct target_rlimit *target_rlim;
6318
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6319
                goto efault;
6320
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6321
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6322
            unlock_user_struct(target_rlim, arg2, 1);
6323
        }
6324
        break;
6325
    }
6326
#endif
6327
#ifdef TARGET_NR_truncate64
6328
    case TARGET_NR_truncate64:
6329
        if (!(p = lock_user_string(arg1)))
6330
            goto efault;
6331
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6332
        unlock_user(p, arg1, 0);
6333
        break;
6334
#endif
6335
#ifdef TARGET_NR_ftruncate64
6336
    case TARGET_NR_ftruncate64:
6337
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6338
        break;
6339
#endif
6340
#ifdef TARGET_NR_stat64
6341
    case TARGET_NR_stat64:
6342
        if (!(p = lock_user_string(arg1)))
6343
            goto efault;
6344
        ret = get_errno(stat(path(p), &st));
6345
        unlock_user(p, arg1, 0);
6346
        if (!is_error(ret))
6347
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6348
        break;
6349
#endif
6350
#ifdef TARGET_NR_lstat64
6351
    case TARGET_NR_lstat64:
6352
        if (!(p = lock_user_string(arg1)))
6353
            goto efault;
6354
        ret = get_errno(lstat(path(p), &st));
6355
        unlock_user(p, arg1, 0);
6356
        if (!is_error(ret))
6357
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6358
        break;
6359
#endif
6360
#ifdef TARGET_NR_fstat64
6361
    case TARGET_NR_fstat64:
6362
        ret = get_errno(fstat(arg1, &st));
6363
        if (!is_error(ret))
6364
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6365
        break;
6366
#endif
6367
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6368
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6369
#ifdef TARGET_NR_fstatat64
6370
    case TARGET_NR_fstatat64:
6371
#endif
6372
#ifdef TARGET_NR_newfstatat
6373
    case TARGET_NR_newfstatat:
6374
#endif
6375
        if (!(p = lock_user_string(arg2)))
6376
            goto efault;
6377
#ifdef __NR_fstatat64
6378
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6379
#else
6380
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6381
#endif
6382
        if (!is_error(ret))
6383
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6384
        break;
6385
#endif
6386
#ifdef USE_UID16
6387
    case TARGET_NR_lchown:
6388
        if (!(p = lock_user_string(arg1)))
6389
            goto efault;
6390
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6391
        unlock_user(p, arg1, 0);
6392
        break;
6393
    case TARGET_NR_getuid:
6394
        ret = get_errno(high2lowuid(getuid()));
6395
        break;
6396
    case TARGET_NR_getgid:
6397
        ret = get_errno(high2lowgid(getgid()));
6398
        break;
6399
    case TARGET_NR_geteuid:
6400
        ret = get_errno(high2lowuid(geteuid()));
6401
        break;
6402
    case TARGET_NR_getegid:
6403
        ret = get_errno(high2lowgid(getegid()));
6404
        break;
6405
    case TARGET_NR_setreuid:
6406
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6407
        break;
6408
    case TARGET_NR_setregid:
6409
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6410
        break;
6411
    case TARGET_NR_getgroups:
6412
        {
6413
            int gidsetsize = arg1;
6414
            uint16_t *target_grouplist;
6415
            gid_t *grouplist;
6416
            int i;
6417

    
6418
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6419
            ret = get_errno(getgroups(gidsetsize, grouplist));
6420
            if (gidsetsize == 0)
6421
                break;
6422
            if (!is_error(ret)) {
6423
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6424
                if (!target_grouplist)
6425
                    goto efault;
6426
                for(i = 0;i < ret; i++)
6427
                    target_grouplist[i] = tswap16(grouplist[i]);
6428
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6429
            }
6430
        }
6431
        break;
6432
    case TARGET_NR_setgroups:
6433
        {
6434
            int gidsetsize = arg1;
6435
            uint16_t *target_grouplist;
6436
            gid_t *grouplist;
6437
            int i;
6438

    
6439
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6440
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6441
            if (!target_grouplist) {
6442
                ret = -TARGET_EFAULT;
6443
                goto fail;
6444
            }
6445
            for(i = 0;i < gidsetsize; i++)
6446
                grouplist[i] = tswap16(target_grouplist[i]);
6447
            unlock_user(target_grouplist, arg2, 0);
6448
            ret = get_errno(setgroups(gidsetsize, grouplist));
6449
        }
6450
        break;
6451
    case TARGET_NR_fchown:
6452
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6453
        break;
6454
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6455
    case TARGET_NR_fchownat:
6456
        if (!(p = lock_user_string(arg2))) 
6457
            goto efault;
6458
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6459
        unlock_user(p, arg2, 0);
6460
        break;
6461
#endif
6462
#ifdef TARGET_NR_setresuid
6463
    case TARGET_NR_setresuid:
6464
        ret = get_errno(setresuid(low2highuid(arg1),
6465
                                  low2highuid(arg2),
6466
                                  low2highuid(arg3)));
6467
        break;
6468
#endif
6469
#ifdef TARGET_NR_getresuid
6470
    case TARGET_NR_getresuid:
6471
        {
6472
            uid_t ruid, euid, suid;
6473
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6474
            if (!is_error(ret)) {
6475
                if (put_user_u16(high2lowuid(ruid), arg1)
6476
                    || put_user_u16(high2lowuid(euid), arg2)
6477
                    || put_user_u16(high2lowuid(suid), arg3))
6478
                    goto efault;
6479
            }
6480
        }
6481
        break;
6482
#endif
6483
#ifdef TARGET_NR_getresgid
6484
    case TARGET_NR_setresgid:
6485
        ret = get_errno(setresgid(low2highgid(arg1),
6486
                                  low2highgid(arg2),
6487
                                  low2highgid(arg3)));
6488
        break;
6489
#endif
6490
#ifdef TARGET_NR_getresgid
6491
    case TARGET_NR_getresgid:
6492
        {
6493
            gid_t rgid, egid, sgid;
6494
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6495
            if (!is_error(ret)) {
6496
                if (put_user_u16(high2lowgid(rgid), arg1)
6497
                    || put_user_u16(high2lowgid(egid), arg2)
6498
                    || put_user_u16(high2lowgid(sgid), arg3))
6499
                    goto efault;
6500
            }
6501
        }
6502
        break;
6503
#endif
6504
    case TARGET_NR_chown:
6505
        if (!(p = lock_user_string(arg1)))
6506
            goto efault;
6507
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6508
        unlock_user(p, arg1, 0);
6509
        break;
6510
    case TARGET_NR_setuid:
6511
        ret = get_errno(setuid(low2highuid(arg1)));
6512
        break;
6513
    case TARGET_NR_setgid:
6514
        ret = get_errno(setgid(low2highgid(arg1)));
6515
        break;
6516
    case TARGET_NR_setfsuid:
6517
        ret = get_errno(setfsuid(arg1));
6518
        break;
6519
    case TARGET_NR_setfsgid:
6520
        ret = get_errno(setfsgid(arg1));
6521
        break;
6522
#endif /* USE_UID16 */
6523

    
6524
#ifdef TARGET_NR_lchown32
6525
    case TARGET_NR_lchown32:
6526
        if (!(p = lock_user_string(arg1)))
6527
            goto efault;
6528
        ret = get_errno(lchown(p, arg2, arg3));
6529
        unlock_user(p, arg1, 0);
6530
        break;
6531
#endif
6532
#ifdef TARGET_NR_getuid32
6533
    case TARGET_NR_getuid32:
6534
        ret = get_errno(getuid());
6535
        break;
6536
#endif
6537

    
6538
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6539
   /* Alpha specific */
6540
    case TARGET_NR_getxuid:
6541
         {
6542
            uid_t euid;
6543
            euid=geteuid();
6544
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6545
         }
6546
        ret = get_errno(getuid());
6547
        break;
6548
#endif
6549
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6550
   /* Alpha specific */
6551
    case TARGET_NR_getxgid:
6552
         {
6553
            uid_t egid;
6554
            egid=getegid();
6555
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6556
         }
6557
        ret = get_errno(getgid());
6558
        break;
6559
#endif
6560
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
6561
    /* Alpha specific */
6562
    case TARGET_NR_osf_getsysinfo:
6563
        ret = -TARGET_EOPNOTSUPP;
6564
        switch (arg1) {
6565
          case TARGET_GSI_IEEE_FP_CONTROL:
6566
            {
6567
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
6568

    
6569
                /* Copied from linux ieee_fpcr_to_swcr.  */
6570
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
6571
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
6572
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
6573
                                        | SWCR_TRAP_ENABLE_DZE
6574
                                        | SWCR_TRAP_ENABLE_OVF);
6575
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
6576
                                        | SWCR_TRAP_ENABLE_INE);
6577
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
6578
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
6579

    
6580
                if (put_user_u64 (swcr, arg2))
6581
                        goto efault;
6582
                ret = 0;
6583
            }
6584
            break;
6585

    
6586
          /* case GSI_IEEE_STATE_AT_SIGNAL:
6587
             -- Not implemented in linux kernel.
6588
             case GSI_UACPROC:
6589
             -- Retrieves current unaligned access state; not much used.
6590
             case GSI_PROC_TYPE:
6591
             -- Retrieves implver information; surely not used.
6592
             case GSI_GET_HWRPB:
6593
             -- Grabs a copy of the HWRPB; surely not used.
6594
          */
6595
        }
6596
        break;
6597
#endif
6598
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
6599
    /* Alpha specific */
6600
    case TARGET_NR_osf_setsysinfo:
6601
        ret = -TARGET_EOPNOTSUPP;
6602
        switch (arg1) {
6603
          case TARGET_SSI_IEEE_FP_CONTROL:
6604
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
6605
            {
6606
                uint64_t swcr, fpcr, orig_fpcr;
6607

    
6608
                if (get_user_u64 (swcr, arg2))
6609
                    goto efault;
6610
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6611
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6612

    
6613
                /* Copied from linux ieee_swcr_to_fpcr.  */
6614
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
6615
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
6616
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
6617
                                  | SWCR_TRAP_ENABLE_DZE
6618
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
6619
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
6620
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
6621
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
6622
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
6623

    
6624
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6625
                ret = 0;
6626

    
6627
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6628
                    /* Old exceptions are not signaled.  */
6629
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6630

    
6631
                    /* If any exceptions set by this call, and are unmasked,
6632
                       send a signal.  */
6633
                    /* ??? FIXME */
6634
                }
6635
            }
6636
            break;
6637

    
6638
          /* case SSI_NVPAIRS:
6639
             -- Used with SSIN_UACPROC to enable unaligned accesses.
6640
             case SSI_IEEE_STATE_AT_SIGNAL:
6641
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
6642
             -- Not implemented in linux kernel
6643
          */
6644
        }
6645
        break;
6646
#endif
6647
#ifdef TARGET_NR_osf_sigprocmask
6648
    /* Alpha specific.  */
6649
    case TARGET_NR_osf_sigprocmask:
6650
        {
6651
            abi_ulong mask;
6652
            int how = arg1;
6653
            sigset_t set, oldset;
6654

    
6655
            switch(arg1) {
6656
            case TARGET_SIG_BLOCK:
6657
                how = SIG_BLOCK;
6658
                break;
6659
            case TARGET_SIG_UNBLOCK:
6660
                how = SIG_UNBLOCK;
6661
                break;
6662
            case TARGET_SIG_SETMASK:
6663
                how = SIG_SETMASK;
6664
                break;
6665
            default:
6666
                ret = -TARGET_EINVAL;
6667
                goto fail;
6668
            }
6669
            mask = arg2;
6670
            target_to_host_old_sigset(&set, &mask);
6671
            sigprocmask(arg1, &set, &oldset);
6672
            host_to_target_old_sigset(&mask, &oldset);
6673
            ret = mask;
6674
        }
6675
        break;
6676
#endif
6677

    
6678
#ifdef TARGET_NR_getgid32
6679
    case TARGET_NR_getgid32:
6680
        ret = get_errno(getgid());
6681
        break;
6682
#endif
6683
#ifdef TARGET_NR_geteuid32
6684
    case TARGET_NR_geteuid32:
6685
        ret = get_errno(geteuid());
6686
        break;
6687
#endif
6688
#ifdef TARGET_NR_getegid32
6689
    case TARGET_NR_getegid32:
6690
        ret = get_errno(getegid());
6691
        break;
6692
#endif
6693
#ifdef TARGET_NR_setreuid32
6694
    case TARGET_NR_setreuid32:
6695
        ret = get_errno(setreuid(arg1, arg2));
6696
        break;
6697
#endif
6698
#ifdef TARGET_NR_setregid32
6699
    case TARGET_NR_setregid32:
6700
        ret = get_errno(setregid(arg1, arg2));
6701
        break;
6702
#endif
6703
#ifdef TARGET_NR_getgroups32
6704
    case TARGET_NR_getgroups32:
6705
        {
6706
            int gidsetsize = arg1;
6707
            uint32_t *target_grouplist;
6708
            gid_t *grouplist;
6709
            int i;
6710

    
6711
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6712
            ret = get_errno(getgroups(gidsetsize, grouplist));
6713
            if (gidsetsize == 0)
6714
                break;
6715
            if (!is_error(ret)) {
6716
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6717
                if (!target_grouplist) {
6718
                    ret = -TARGET_EFAULT;
6719
                    goto fail;
6720
                }
6721
                for(i = 0;i < ret; i++)
6722
                    target_grouplist[i] = tswap32(grouplist[i]);
6723
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6724
            }
6725
        }
6726
        break;
6727
#endif
6728
#ifdef TARGET_NR_setgroups32
6729
    case TARGET_NR_setgroups32:
6730
        {
6731
            int gidsetsize = arg1;
6732
            uint32_t *target_grouplist;
6733
            gid_t *grouplist;
6734
            int i;
6735

    
6736
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6737
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6738
            if (!target_grouplist) {
6739
                ret = -TARGET_EFAULT;
6740
                goto fail;
6741
            }
6742
            for(i = 0;i < gidsetsize; i++)
6743
                grouplist[i] = tswap32(target_grouplist[i]);
6744
            unlock_user(target_grouplist, arg2, 0);
6745
            ret = get_errno(setgroups(gidsetsize, grouplist));
6746
        }
6747
        break;
6748
#endif
6749
#ifdef TARGET_NR_fchown32
6750
    case TARGET_NR_fchown32:
6751
        ret = get_errno(fchown(arg1, arg2, arg3));
6752
        break;
6753
#endif
6754
#ifdef TARGET_NR_setresuid32
6755
    case TARGET_NR_setresuid32:
6756
        ret = get_errno(setresuid(arg1, arg2, arg3));
6757
        break;
6758
#endif
6759
#ifdef TARGET_NR_getresuid32
6760
    case TARGET_NR_getresuid32:
6761
        {
6762
            uid_t ruid, euid, suid;
6763
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6764
            if (!is_error(ret)) {
6765
                if (put_user_u32(ruid, arg1)
6766
                    || put_user_u32(euid, arg2)
6767
                    || put_user_u32(suid, arg3))
6768
                    goto efault;
6769
            }
6770
        }
6771
        break;
6772
#endif
6773
#ifdef TARGET_NR_setresgid32
6774
    case TARGET_NR_setresgid32:
6775
        ret = get_errno(setresgid(arg1, arg2, arg3));
6776
        break;
6777
#endif
6778
#ifdef TARGET_NR_getresgid32
6779
    case TARGET_NR_getresgid32:
6780
        {
6781
            gid_t rgid, egid, sgid;
6782
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6783
            if (!is_error(ret)) {
6784
                if (put_user_u32(rgid, arg1)
6785
                    || put_user_u32(egid, arg2)
6786
                    || put_user_u32(sgid, arg3))
6787
                    goto efault;
6788
            }
6789
        }
6790
        break;
6791
#endif
6792
#ifdef TARGET_NR_chown32
6793
    case TARGET_NR_chown32:
6794
        if (!(p = lock_user_string(arg1)))
6795
            goto efault;
6796
        ret = get_errno(chown(p, arg2, arg3));
6797
        unlock_user(p, arg1, 0);
6798
        break;
6799
#endif
6800
#ifdef TARGET_NR_setuid32
6801
    case TARGET_NR_setuid32:
6802
        ret = get_errno(setuid(arg1));
6803
        break;
6804
#endif
6805
#ifdef TARGET_NR_setgid32
6806
    case TARGET_NR_setgid32:
6807
        ret = get_errno(setgid(arg1));
6808
        break;
6809
#endif
6810
#ifdef TARGET_NR_setfsuid32
6811
    case TARGET_NR_setfsuid32:
6812
        ret = get_errno(setfsuid(arg1));
6813
        break;
6814
#endif
6815
#ifdef TARGET_NR_setfsgid32
6816
    case TARGET_NR_setfsgid32:
6817
        ret = get_errno(setfsgid(arg1));
6818
        break;
6819
#endif
6820

    
6821
    case TARGET_NR_pivot_root:
6822
        goto unimplemented;
6823
#ifdef TARGET_NR_mincore
6824
    case TARGET_NR_mincore:
6825
        {
6826
            void *a;
6827
            ret = -TARGET_EFAULT;
6828
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6829
                goto efault;
6830
            if (!(p = lock_user_string(arg3)))
6831
                goto mincore_fail;
6832
            ret = get_errno(mincore(a, arg2, p));
6833
            unlock_user(p, arg3, ret);
6834
            mincore_fail:
6835
            unlock_user(a, arg1, 0);
6836
        }
6837
        break;
6838
#endif
6839
#ifdef TARGET_NR_arm_fadvise64_64
6840
    case TARGET_NR_arm_fadvise64_64:
6841
        {
6842
                /*
6843
                 * arm_fadvise64_64 looks like fadvise64_64 but
6844
                 * with different argument order
6845
                 */
6846
                abi_long temp;
6847
                temp = arg3;
6848
                arg3 = arg4;
6849
                arg4 = temp;
6850
        }
6851
#endif
6852
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
6853
#ifdef TARGET_NR_fadvise64_64
6854
    case TARGET_NR_fadvise64_64:
6855
#endif
6856
#ifdef TARGET_NR_fadvise64
6857
    case TARGET_NR_fadvise64:
6858
#endif
6859
#ifdef TARGET_S390X
6860
        switch (arg4) {
6861
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
6862
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
6863
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
6864
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
6865
        default: break;
6866
        }
6867
#endif
6868
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
6869
        break;
6870
#endif
6871
#ifdef TARGET_NR_madvise
6872
    case TARGET_NR_madvise:
6873
        /* A straight passthrough may not be safe because qemu sometimes
6874
           turns private flie-backed mappings into anonymous mappings.
6875
           This will break MADV_DONTNEED.
6876
           This is a hint, so ignoring and returning success is ok.  */
6877
        ret = get_errno(0);
6878
        break;
6879
#endif
6880
#if TARGET_ABI_BITS == 32
6881
    case TARGET_NR_fcntl64:
6882
    {
6883
        int cmd;
6884
        struct flock64 fl;
6885
        struct target_flock64 *target_fl;
6886
#ifdef TARGET_ARM
6887
        struct target_eabi_flock64 *target_efl;
6888
#endif
6889

    
6890
        cmd = target_to_host_fcntl_cmd(arg2);
6891
        if (cmd == -TARGET_EINVAL)
6892
                return cmd;
6893

    
6894
        switch(arg2) {
6895
        case TARGET_F_GETLK64:
6896
#ifdef TARGET_ARM
6897
            if (((CPUARMState *)cpu_env)->eabi) {
6898
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6899
                    goto efault;
6900
                fl.l_type = tswap16(target_efl->l_type);
6901
                fl.l_whence = tswap16(target_efl->l_whence);
6902
                fl.l_start = tswap64(target_efl->l_start);
6903
                fl.l_len = tswap64(target_efl->l_len);
6904
                fl.l_pid = tswap32(target_efl->l_pid);
6905
                unlock_user_struct(target_efl, arg3, 0);
6906
            } else
6907
#endif
6908
            {
6909
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6910
                    goto efault;
6911
                fl.l_type = tswap16(target_fl->l_type);
6912
                fl.l_whence = tswap16(target_fl->l_whence);
6913
                fl.l_start = tswap64(target_fl->l_start);
6914
                fl.l_len = tswap64(target_fl->l_len);
6915
                fl.l_pid = tswap32(target_fl->l_pid);
6916
                unlock_user_struct(target_fl, arg3, 0);
6917
            }
6918
            ret = get_errno(fcntl(arg1, cmd, &fl));
6919
            if (ret == 0) {
6920
#ifdef TARGET_ARM
6921
                if (((CPUARMState *)cpu_env)->eabi) {
6922
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6923
                        goto efault;
6924
                    target_efl->l_type = tswap16(fl.l_type);
6925
                    target_efl->l_whence = tswap16(fl.l_whence);
6926
                    target_efl->l_start = tswap64(fl.l_start);
6927
                    target_efl->l_len = tswap64(fl.l_len);
6928
                    target_efl->l_pid = tswap32(fl.l_pid);
6929
                    unlock_user_struct(target_efl, arg3, 1);
6930
                } else
6931
#endif
6932
                {
6933
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6934
                        goto efault;
6935
                    target_fl->l_type = tswap16(fl.l_type);
6936
                    target_fl->l_whence = tswap16(fl.l_whence);
6937
                    target_fl->l_start = tswap64(fl.l_start);
6938
                    target_fl->l_len = tswap64(fl.l_len);
6939
                    target_fl->l_pid = tswap32(fl.l_pid);
6940
                    unlock_user_struct(target_fl, arg3, 1);
6941
                }
6942
            }
6943
            break;
6944

    
6945
        case TARGET_F_SETLK64:
6946
        case TARGET_F_SETLKW64:
6947
#ifdef TARGET_ARM
6948
            if (((CPUARMState *)cpu_env)->eabi) {
6949
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6950
                    goto efault;
6951
                fl.l_type = tswap16(target_efl->l_type);
6952
                fl.l_whence = tswap16(target_efl->l_whence);
6953
                fl.l_start = tswap64(target_efl->l_start);
6954
                fl.l_len = tswap64(target_efl->l_len);
6955
                fl.l_pid = tswap32(target_efl->l_pid);
6956
                unlock_user_struct(target_efl, arg3, 0);
6957
            } else
6958
#endif
6959
            {
6960
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6961
                    goto efault;
6962
                fl.l_type = tswap16(target_fl->l_type);
6963
                fl.l_whence = tswap16(target_fl->l_whence);
6964
                fl.l_start = tswap64(target_fl->l_start);
6965
                fl.l_len = tswap64(target_fl->l_len);
6966
                fl.l_pid = tswap32(target_fl->l_pid);
6967
                unlock_user_struct(target_fl, arg3, 0);
6968
            }
6969
            ret = get_errno(fcntl(arg1, cmd, &fl));
6970
            break;
6971
        default:
6972
            ret = do_fcntl(arg1, arg2, arg3);
6973
            break;
6974
        }
6975
        break;
6976
    }
6977
#endif
6978
#ifdef TARGET_NR_cacheflush
6979
    case TARGET_NR_cacheflush:
6980
        /* self-modifying code is handled automatically, so nothing needed */
6981
        ret = 0;
6982
        break;
6983
#endif
6984
#ifdef TARGET_NR_security
6985
    case TARGET_NR_security:
6986
        goto unimplemented;
6987
#endif
6988
#ifdef TARGET_NR_getpagesize
6989
    case TARGET_NR_getpagesize:
6990
        ret = TARGET_PAGE_SIZE;
6991
        break;
6992
#endif
6993
    case TARGET_NR_gettid:
6994
        ret = get_errno(gettid());
6995
        break;
6996
#ifdef TARGET_NR_readahead
6997
    case TARGET_NR_readahead:
6998
#if TARGET_ABI_BITS == 32
6999
#ifdef TARGET_ARM
7000
        if (((CPUARMState *)cpu_env)->eabi)
7001
        {
7002
            arg2 = arg3;
7003
            arg3 = arg4;
7004
            arg4 = arg5;
7005
        }
7006
#endif
7007
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
7008
#else
7009
        ret = get_errno(readahead(arg1, arg2, arg3));
7010
#endif
7011
        break;
7012
#endif
7013
#ifdef TARGET_NR_setxattr
7014
    case TARGET_NR_setxattr:
7015
    case TARGET_NR_lsetxattr:
7016
    case TARGET_NR_fsetxattr:
7017
    case TARGET_NR_getxattr:
7018
    case TARGET_NR_lgetxattr:
7019
    case TARGET_NR_fgetxattr:
7020
    case TARGET_NR_listxattr:
7021
    case TARGET_NR_llistxattr:
7022
    case TARGET_NR_flistxattr:
7023
    case TARGET_NR_removexattr:
7024
    case TARGET_NR_lremovexattr:
7025
    case TARGET_NR_fremovexattr:
7026
        ret = -TARGET_EOPNOTSUPP;
7027
        break;
7028
#endif
7029
#ifdef TARGET_NR_set_thread_area
7030
    case TARGET_NR_set_thread_area:
7031
#if defined(TARGET_MIPS)
7032
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
7033
      ret = 0;
7034
      break;
7035
#elif defined(TARGET_CRIS)
7036
      if (arg1 & 0xff)
7037
          ret = -TARGET_EINVAL;
7038
      else {
7039
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
7040
          ret = 0;
7041
      }
7042
      break;
7043
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
7044
      ret = do_set_thread_area(cpu_env, arg1);
7045
      break;
7046
#else
7047
      goto unimplemented_nowarn;
7048
#endif
7049
#endif
7050
#ifdef TARGET_NR_get_thread_area
7051
    case TARGET_NR_get_thread_area:
7052
#if defined(TARGET_I386) && defined(TARGET_ABI32)
7053
        ret = do_get_thread_area(cpu_env, arg1);
7054
#else
7055
        goto unimplemented_nowarn;
7056
#endif
7057
#endif
7058
#ifdef TARGET_NR_getdomainname
7059
    case TARGET_NR_getdomainname:
7060
        goto unimplemented_nowarn;
7061
#endif
7062

    
7063
#ifdef TARGET_NR_clock_gettime
7064
    case TARGET_NR_clock_gettime:
7065
    {
7066
        struct timespec ts;
7067
        ret = get_errno(clock_gettime(arg1, &ts));
7068
        if (!is_error(ret)) {
7069
            host_to_target_timespec(arg2, &ts);
7070
        }
7071
        break;
7072
    }
7073
#endif
7074
#ifdef TARGET_NR_clock_getres
7075
    case TARGET_NR_clock_getres:
7076
    {
7077
        struct timespec ts;
7078
        ret = get_errno(clock_getres(arg1, &ts));
7079
        if (!is_error(ret)) {
7080
            host_to_target_timespec(arg2, &ts);
7081
        }
7082
        break;
7083
    }
7084
#endif
7085
#ifdef TARGET_NR_clock_nanosleep
7086
    case TARGET_NR_clock_nanosleep:
7087
    {
7088
        struct timespec ts;
7089
        target_to_host_timespec(&ts, arg3);
7090
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
7091
        if (arg4)
7092
            host_to_target_timespec(arg4, &ts);
7093
        break;
7094
    }
7095
#endif
7096

    
7097
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7098
    case TARGET_NR_set_tid_address:
7099
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7100
        break;
7101
#endif
7102

    
7103
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7104
    case TARGET_NR_tkill:
7105
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7106
        break;
7107
#endif
7108

    
7109
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7110
    case TARGET_NR_tgkill:
7111
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7112
                        target_to_host_signal(arg3)));
7113
        break;
7114
#endif
7115

    
7116
#ifdef TARGET_NR_set_robust_list
7117
    case TARGET_NR_set_robust_list:
7118
        goto unimplemented_nowarn;
7119
#endif
7120

    
7121
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7122
    case TARGET_NR_utimensat:
7123
        {
7124
            struct timespec *tsp, ts[2];
7125
            if (!arg3) {
7126
                tsp = NULL;
7127
            } else {
7128
                target_to_host_timespec(ts, arg3);
7129
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7130
                tsp = ts;
7131
            }
7132
            if (!arg2)
7133
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7134
            else {
7135
                if (!(p = lock_user_string(arg2))) {
7136
                    ret = -TARGET_EFAULT;
7137
                    goto fail;
7138
                }
7139
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7140
                unlock_user(p, arg2, 0);
7141
            }
7142
        }
7143
        break;
7144
#endif
7145
#if defined(CONFIG_USE_NPTL)
7146
    case TARGET_NR_futex:
7147
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7148
        break;
7149
#endif
7150
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7151
    case TARGET_NR_inotify_init:
7152
        ret = get_errno(sys_inotify_init());
7153
        break;
7154
#endif
7155
#ifdef CONFIG_INOTIFY1
7156
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
7157
    case TARGET_NR_inotify_init1:
7158
        ret = get_errno(sys_inotify_init1(arg1));
7159
        break;
7160
#endif
7161
#endif
7162
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7163
    case TARGET_NR_inotify_add_watch:
7164
        p = lock_user_string(arg2);
7165
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7166
        unlock_user(p, arg2, 0);
7167
        break;
7168
#endif
7169
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7170
    case TARGET_NR_inotify_rm_watch:
7171
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7172
        break;
7173
#endif
7174

    
7175
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7176
    case TARGET_NR_mq_open:
7177
        {
7178
            struct mq_attr posix_mq_attr;
7179

    
7180
            p = lock_user_string(arg1 - 1);
7181
            if (arg4 != 0)
7182
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7183
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7184
            unlock_user (p, arg1, 0);
7185
        }
7186
        break;
7187

    
7188
    case TARGET_NR_mq_unlink:
7189
        p = lock_user_string(arg1 - 1);
7190
        ret = get_errno(mq_unlink(p));
7191
        unlock_user (p, arg1, 0);
7192
        break;
7193

    
7194
    case TARGET_NR_mq_timedsend:
7195
        {
7196
            struct timespec ts;
7197

    
7198
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7199
            if (arg5 != 0) {
7200
                target_to_host_timespec(&ts, arg5);
7201
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7202
                host_to_target_timespec(arg5, &ts);
7203
            }
7204
            else
7205
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7206
            unlock_user (p, arg2, arg3);
7207
        }
7208
        break;
7209

    
7210
    case TARGET_NR_mq_timedreceive:
7211
        {
7212
            struct timespec ts;
7213
            unsigned int prio;
7214

    
7215
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7216
            if (arg5 != 0) {
7217
                target_to_host_timespec(&ts, arg5);
7218
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7219
                host_to_target_timespec(arg5, &ts);
7220
            }
7221
            else
7222
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7223
            unlock_user (p, arg2, arg3);
7224
            if (arg4 != 0)
7225
                put_user_u32(prio, arg4);
7226
        }
7227
        break;
7228

    
7229
    /* Not implemented for now... */
7230
/*     case TARGET_NR_mq_notify: */
7231
/*         break; */
7232

    
7233
    case TARGET_NR_mq_getsetattr:
7234
        {
7235
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7236
            ret = 0;
7237
            if (arg3 != 0) {
7238
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7239
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7240
            }
7241
            if (arg2 != 0) {
7242
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7243
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7244
            }
7245

    
7246
        }
7247
        break;
7248
#endif
7249

    
7250
#ifdef CONFIG_SPLICE
7251
#ifdef TARGET_NR_tee
7252
    case TARGET_NR_tee:
7253
        {
7254
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7255
        }
7256
        break;
7257
#endif
7258
#ifdef TARGET_NR_splice
7259
    case TARGET_NR_splice:
7260
        {
7261
            loff_t loff_in, loff_out;
7262
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7263
            if(arg2) {
7264
                get_user_u64(loff_in, arg2);
7265
                ploff_in = &loff_in;
7266
            }
7267
            if(arg4) {
7268
                get_user_u64(loff_out, arg2);
7269
                ploff_out = &loff_out;
7270
            }
7271
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7272
        }
7273
        break;
7274
#endif
7275
#ifdef TARGET_NR_vmsplice
7276
        case TARGET_NR_vmsplice:
7277
        {
7278
            int count = arg3;
7279
            struct iovec *vec;
7280

    
7281
            vec = alloca(count * sizeof(struct iovec));
7282
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7283
                goto efault;
7284
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7285
            unlock_iovec(vec, arg2, count, 0);
7286
        }
7287
        break;
7288
#endif
7289
#endif /* CONFIG_SPLICE */
7290
#ifdef CONFIG_EVENTFD
7291
#if defined(TARGET_NR_eventfd)
7292
    case TARGET_NR_eventfd:
7293
        ret = get_errno(eventfd(arg1, 0));
7294
        break;
7295
#endif
7296
#if defined(TARGET_NR_eventfd2)
7297
    case TARGET_NR_eventfd2:
7298
        ret = get_errno(eventfd(arg1, arg2));
7299
        break;
7300
#endif
7301
#endif /* CONFIG_EVENTFD  */
7302
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7303
    case TARGET_NR_fallocate:
7304
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7305
        break;
7306
#endif
7307
    default:
7308
    unimplemented:
7309
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7310
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7311
    unimplemented_nowarn:
7312
#endif
7313
        ret = -TARGET_ENOSYS;
7314
        break;
7315
    }
7316
fail:
7317
#ifdef DEBUG
7318
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7319
#endif
7320
    if(do_strace)
7321
        print_syscall_ret(num, ret);
7322
    return ret;
7323
efault:
7324
    ret = -TARGET_EFAULT;
7325
    goto fail;
7326
}