Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ c4ab7899

History | View | Annotate | Download (219.8 kB)

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

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

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

    
87
#include "qemu.h"
88
#include "qemu-common.h"
89

    
90
#if defined(CONFIG_USE_NPTL)
91
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
92
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
93
#else
94
/* XXX: Hardcode the above values.  */
95
#define CLONE_NPTL_FLAGS2 0
96
#endif
97

    
98
//#define DEBUG
99

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

    
104

    
105
#undef _syscall0
106
#undef _syscall1
107
#undef _syscall2
108
#undef _syscall3
109
#undef _syscall4
110
#undef _syscall5
111
#undef _syscall6
112

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

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

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

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

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

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

    
150

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

    
159

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

    
189
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
190
#define __NR__llseek __NR_lseek
191
#endif
192

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

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

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

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

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

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

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

    
283
#undef COPY_UTSNAME_FIELD
284
}
285

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

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

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

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

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

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

    
470
#endif /* CONFIG_ATFILE */
471

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

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

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

    
516

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

    
523
#define ERRNO_TABLE_SIZE 1200
524

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

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

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

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

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

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

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

    
674
static abi_ulong target_brk;
675
static abi_ulong target_original_brk;
676

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

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

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

    
694
    brk_page = HOST_PAGE_ALIGN(target_brk);
695

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

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

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

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

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

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

    
741
    unlock_user(target_fds, target_fds_addr, 0);
742

    
743
    return 0;
744
}
745

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

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

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

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

    
773
    return 0;
774
}
775

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

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

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

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

    
818
    return 0;
819
}
820

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

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

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

    
832
    unlock_user_struct(target_tv, target_tv_addr, 0);
833

    
834
    return 0;
835
}
836

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

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

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

    
848
    unlock_user_struct(target_tv, target_tv_addr, 1);
849

    
850
    return 0;
851
}
852

    
853
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
854
#include <mqueue.h>
855

    
856
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
857
                                              abi_ulong target_mq_attr_addr)
858
{
859
    struct target_mq_attr *target_mq_attr;
860

    
861
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
862
                          target_mq_attr_addr, 1))
863
        return -TARGET_EFAULT;
864

    
865
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
866
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
867
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
868
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
869

    
870
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
871

    
872
    return 0;
873
}
874

    
875
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
876
                                            const struct mq_attr *attr)
877
{
878
    struct target_mq_attr *target_mq_attr;
879

    
880
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
881
                          target_mq_attr_addr, 0))
882
        return -TARGET_EFAULT;
883

    
884
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
885
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
886
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
887
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
888

    
889
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
890

    
891
    return 0;
892
}
893
#endif
894

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

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

    
927
    if (target_tv_addr) {
928
        if (copy_from_user_timeval(&tv, target_tv_addr))
929
            return -TARGET_EFAULT;
930
        tv_ptr = &tv;
931
    } else {
932
        tv_ptr = NULL;
933
    }
934

    
935
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
936

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

    
945
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
946
            return -TARGET_EFAULT;
947
    }
948

    
949
    return ret;
950
}
951

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

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

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

    
983
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
984
                                              abi_ulong target_addr,
985
                                              socklen_t len)
986
{
987
    struct target_ip_mreqn *target_smreqn;
988

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

    
998
    return 0;
999
}
1000

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

    
1009
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1010
    if (!target_saddr)
1011
        return -TARGET_EFAULT;
1012

    
1013
    sa_family = tswap16(target_saddr->sa_family);
1014

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

    
1023
    if (sa_family == AF_UNIX) {
1024
        if (len < unix_maxlen && len > 0) {
1025
            char *cp = (char*)target_saddr;
1026

    
1027
            if ( cp[len-1] && !cp[len] )
1028
                len++;
1029
        }
1030
        if (len > unix_maxlen)
1031
            len = unix_maxlen;
1032
    }
1033

    
1034
    memcpy(addr, target_saddr, len);
1035
    addr->sa_family = sa_family;
1036
    unlock_user(target_saddr, target_addr, 0);
1037

    
1038
    return 0;
1039
}
1040

    
1041
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1042
                                               struct sockaddr *addr,
1043
                                               socklen_t len)
1044
{
1045
    struct target_sockaddr *target_saddr;
1046

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

    
1054
    return 0;
1055
}
1056

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

    
1075
    while (cmsg && target_cmsg) {
1076
        void *data = CMSG_DATA(cmsg);
1077
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1078

    
1079
        int len = tswapl(target_cmsg->cmsg_len)
1080
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1081

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

    
1089
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1090
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1091
        cmsg->cmsg_len = CMSG_LEN(len);
1092

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

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

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

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

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

    
1132
    while (cmsg && target_cmsg) {
1133
        void *data = CMSG_DATA(cmsg);
1134
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1135

    
1136
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1137

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

    
1145
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1146
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1147
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1148

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

    
1157
            for (i = 0; i < numfds; i++)
1158
                target_fd[i] = tswap32(fd[i]);
1159
        }
1160

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

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

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

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

    
1222
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1223
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1224
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1225
            break;
1226

    
1227
        case IP_BLOCK_SOURCE:
1228
        case IP_UNBLOCK_SOURCE:
1229
        case IP_ADD_SOURCE_MEMBERSHIP:
1230
        case IP_DROP_SOURCE_MEMBERSHIP:
1231
            if (optlen != sizeof (struct target_ip_mreq_source))
1232
                return -TARGET_EINVAL;
1233

    
1234
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1235
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1236
            unlock_user (ip_mreq_source, optval_addr, 0);
1237
            break;
1238

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

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

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

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

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

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

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

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

    
1468
    return 0;
1469
}
1470

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

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

    
1508
    if (addrlen < 0)
1509
        return -TARGET_EINVAL;
1510

    
1511
    addr = alloca(addrlen+1);
1512

    
1513
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1514
    if (ret)
1515
        return ret;
1516

    
1517
    return get_errno(bind(sockfd, addr, addrlen));
1518
}
1519

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

    
1527
    if (addrlen < 0)
1528
        return -TARGET_EINVAL;
1529

    
1530
    addr = alloca(addrlen);
1531

    
1532
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1533
    if (ret)
1534
        return ret;
1535

    
1536
    return get_errno(connect(sockfd, addr, addrlen));
1537
}
1538

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

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

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

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

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

    
1606
    if (target_addr == 0)
1607
       return get_errno(accept(fd, NULL, NULL));
1608

    
1609
    /* linux returns EINVAL if addrlen pointer is invalid */
1610
    if (get_user_u32(addrlen, target_addrlen_addr))
1611
        return -TARGET_EINVAL;
1612

    
1613
    if (addrlen < 0)
1614
        return -TARGET_EINVAL;
1615

    
1616
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1617
        return -TARGET_EINVAL;
1618

    
1619
    addr = alloca(addrlen);
1620

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

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

    
1638
    if (get_user_u32(addrlen, target_addrlen_addr))
1639
        return -TARGET_EFAULT;
1640

    
1641
    if (addrlen < 0)
1642
        return -TARGET_EINVAL;
1643

    
1644
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1645
        return -TARGET_EFAULT;
1646

    
1647
    addr = alloca(addrlen);
1648

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

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

    
1666
    if (get_user_u32(addrlen, target_addrlen_addr))
1667
        return -TARGET_EFAULT;
1668

    
1669
    if (addrlen < 0)
1670
        return -TARGET_EINVAL;
1671

    
1672
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1673
        return -TARGET_EFAULT;
1674

    
1675
    addr = alloca(addrlen);
1676

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

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

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

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

    
1710
    if (addrlen < 0)
1711
        return -TARGET_EINVAL;
1712

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

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

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

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

    
1782
    switch(num) {
1783
    case SOCKOP_socket:
1784
        {
1785
            abi_ulong domain, type, protocol;
1786

    
1787
            if (get_user_ual(domain, vptr)
1788
                || get_user_ual(type, vptr + n)
1789
                || get_user_ual(protocol, vptr + 2 * n))
1790
                return -TARGET_EFAULT;
1791

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

    
1801
            if (get_user_ual(sockfd, vptr)
1802
                || get_user_ual(target_addr, vptr + n)
1803
                || get_user_ual(addrlen, vptr + 2 * n))
1804
                return -TARGET_EFAULT;
1805

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

    
1815
            if (get_user_ual(sockfd, vptr)
1816
                || get_user_ual(target_addr, vptr + n)
1817
                || get_user_ual(addrlen, vptr + 2 * n))
1818
                return -TARGET_EFAULT;
1819

    
1820
            ret = do_connect(sockfd, target_addr, addrlen);
1821
        }
1822
        break;
1823
    case SOCKOP_listen:
1824
        {
1825
            abi_ulong sockfd, backlog;
1826

    
1827
            if (get_user_ual(sockfd, vptr)
1828
                || get_user_ual(backlog, vptr + n))
1829
                return -TARGET_EFAULT;
1830

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

    
1839
            if (get_user_ual(sockfd, vptr)
1840
                || get_user_ual(target_addr, vptr + n)
1841
                || get_user_ual(target_addrlen, vptr + 2 * n))
1842
                return -TARGET_EFAULT;
1843

    
1844
            ret = do_accept(sockfd, target_addr, target_addrlen);
1845
        }
1846
        break;
1847
    case SOCKOP_getsockname:
1848
        {
1849
            abi_ulong sockfd;
1850
            abi_ulong target_addr, target_addrlen;
1851

    
1852
            if (get_user_ual(sockfd, vptr)
1853
                || get_user_ual(target_addr, vptr + n)
1854
                || get_user_ual(target_addrlen, vptr + 2 * n))
1855
                return -TARGET_EFAULT;
1856

    
1857
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1858
        }
1859
        break;
1860
    case SOCKOP_getpeername:
1861
        {
1862
            abi_ulong sockfd;
1863
            abi_ulong target_addr, target_addrlen;
1864

    
1865
            if (get_user_ual(sockfd, vptr)
1866
                || get_user_ual(target_addr, vptr + n)
1867
                || get_user_ual(target_addrlen, vptr + 2 * n))
1868
                return -TARGET_EFAULT;
1869

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

    
1878
            if (get_user_ual(domain, vptr)
1879
                || get_user_ual(type, vptr + n)
1880
                || get_user_ual(protocol, vptr + 2 * n)
1881
                || get_user_ual(tab, vptr + 3 * n))
1882
                return -TARGET_EFAULT;
1883

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

    
1894
            if (get_user_ual(sockfd, vptr)
1895
                || get_user_ual(msg, vptr + n)
1896
                || get_user_ual(len, vptr + 2 * n)
1897
                || get_user_ual(flags, vptr + 3 * n))
1898
                return -TARGET_EFAULT;
1899

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

    
1910
            if (get_user_ual(sockfd, vptr)
1911
                || get_user_ual(msg, vptr + n)
1912
                || get_user_ual(len, vptr + 2 * n)
1913
                || get_user_ual(flags, vptr + 3 * n))
1914
                return -TARGET_EFAULT;
1915

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

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

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

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

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

    
1963
            if (get_user_ual(sockfd, vptr)
1964
                || get_user_ual(how, vptr + n))
1965
                return -TARGET_EFAULT;
1966

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

    
1977
            if (get_user_ual(fd, vptr)
1978
                || get_user_ual(target_msg, vptr + n)
1979
                || get_user_ual(flags, vptr + 2 * n))
1980
                return -TARGET_EFAULT;
1981

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

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

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

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

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

    
2031
#define N_SHM_REGIONS        32
2032

    
2033
static struct shm_region {
2034
    abi_ulong        start;
2035
    abi_ulong        size;
2036
} shm_regions[N_SHM_REGIONS];
2037

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

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

    
2065
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2066
                                               abi_ulong target_addr)
2067
{
2068
    struct target_ipc_perm *target_ip;
2069
    struct target_semid_ds *target_sd;
2070

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

    
2084
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2085
                                               struct ipc_perm *host_ip)
2086
{
2087
    struct target_ipc_perm *target_ip;
2088
    struct target_semid_ds *target_sd;
2089

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

    
2103
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2104
                                               abi_ulong target_addr)
2105
{
2106
    struct target_semid_ds *target_sd;
2107

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

    
2119
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2120
                                               struct semid_ds *host_sd)
2121
{
2122
    struct target_semid_ds *target_sd;
2123

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

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

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

    
2168
union semun {
2169
        int val;
2170
        struct semid_ds *buf;
2171
        unsigned short *array;
2172
        struct seminfo *__buf;
2173
};
2174

    
2175
union target_semun {
2176
        int val;
2177
        abi_ulong buf;
2178
        abi_ulong array;
2179
        abi_ulong __buf;
2180
};
2181

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

    
2191
    semun.buf = &semid_ds;
2192

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

    
2197
    nsems = semid_ds.sem_nsems;
2198

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

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

    
2210
    return 0;
2211
}
2212

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

    
2222
    semun.buf = &semid_ds;
2223

    
2224
    ret = semctl(semid, 0, IPC_STAT, semun);
2225
    if (ret == -1)
2226
        return get_errno(ret);
2227

    
2228
    nsems = semid_ds.sem_nsems;
2229

    
2230
    array = lock_user(VERIFY_WRITE, target_addr,
2231
                      nsems*sizeof(unsigned short), 0);
2232
    if (!array)
2233
        return -TARGET_EFAULT;
2234

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

    
2241
    return 0;
2242
}
2243

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

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

    
2301
    return ret;
2302
}
2303

    
2304
struct target_sembuf {
2305
    unsigned short sem_num;
2306
    short sem_op;
2307
    short sem_flg;
2308
};
2309

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

    
2317
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2318
                              nsops*sizeof(struct target_sembuf), 1);
2319
    if (!target_sembuf)
2320
        return -TARGET_EFAULT;
2321

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

    
2328
    unlock_user(target_sembuf, target_addr, 0);
2329

    
2330
    return 0;
2331
}
2332

    
2333
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2334
{
2335
    struct sembuf sops[nsops];
2336

    
2337
    if (target_to_host_sembuf(sops, ptr, nsops))
2338
        return -TARGET_EFAULT;
2339

    
2340
    return semop(semid, sops, nsops);
2341
}
2342

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

    
2367
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2368
                                               abi_ulong target_addr)
2369
{
2370
    struct target_msqid_ds *target_md;
2371

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

    
2388
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2389
                                               struct msqid_ds *host_md)
2390
{
2391
    struct target_msqid_ds *target_md;
2392

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

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

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

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

    
2444
    cmd &= 0xff;
2445

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

    
2467
    return ret;
2468
}
2469

    
2470
struct target_msgbuf {
2471
    abi_long mtype;
2472
    char        mtext[1];
2473
};
2474

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

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

    
2491
    return ret;
2492
}
2493

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

    
2503
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2504
        return -TARGET_EFAULT;
2505

    
2506
    host_mb = malloc(msgsz+sizeof(long));
2507
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2508

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

    
2520
    target_mb->mtype = tswapl(host_mb->mtype);
2521
    free(host_mb);
2522

    
2523
end:
2524
    if (target_mb)
2525
        unlock_user_struct(target_mb, msgp, 1);
2526
    return ret;
2527
}
2528

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

    
2552
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2553
                                               abi_ulong target_addr)
2554
{
2555
    struct target_shmid_ds *target_sd;
2556

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

    
2572
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2573
                                               struct shmid_ds *host_sd)
2574
{
2575
    struct target_shmid_ds *target_sd;
2576

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

    
2592
struct  target_shminfo {
2593
    abi_ulong shmmax;
2594
    abi_ulong shmmin;
2595
    abi_ulong shmmni;
2596
    abi_ulong shmseg;
2597
    abi_ulong shmall;
2598
};
2599

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

    
2615
struct target_shm_info {
2616
    int used_ids;
2617
    abi_ulong shm_tot;
2618
    abi_ulong shm_rss;
2619
    abi_ulong shm_swp;
2620
    abi_ulong swap_attempts;
2621
    abi_ulong swap_successes;
2622
};
2623

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

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

    
2647
    cmd &= 0xff;
2648

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

    
2676
    return ret;
2677
}
2678

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

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

    
2693
    mmap_lock();
2694

    
2695
    if (shmaddr)
2696
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2697
    else {
2698
        abi_ulong mmap_start;
2699

    
2700
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2701

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

    
2709
    if (host_raddr == (void *)-1) {
2710
        mmap_unlock();
2711
        return get_errno((long)host_raddr);
2712
    }
2713
    raddr=h2g((unsigned long)host_raddr);
2714

    
2715
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2716
                   PAGE_VALID | PAGE_READ |
2717
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2718

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

    
2727
    mmap_unlock();
2728
    return raddr;
2729

    
2730
}
2731

    
2732
static inline abi_long do_shmdt(abi_ulong shmaddr)
2733
{
2734
    int i;
2735

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

    
2744
    return get_errno(shmdt(g2h(shmaddr)));
2745
}
2746

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

    
2757
    version = call >> 16;
2758
    call &= 0xffff;
2759

    
2760
    switch (call) {
2761
    case IPCOP_semop:
2762
        ret = do_semop(first, ptr, second);
2763
        break;
2764

    
2765
    case IPCOP_semget:
2766
        ret = get_errno(semget(first, second, third));
2767
        break;
2768

    
2769
    case IPCOP_semctl:
2770
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2771
        break;
2772

    
2773
    case IPCOP_msgget:
2774
        ret = get_errno(msgget(first, second));
2775
        break;
2776

    
2777
    case IPCOP_msgsnd:
2778
        ret = do_msgsnd(first, ptr, second, third);
2779
        break;
2780

    
2781
    case IPCOP_msgctl:
2782
        ret = do_msgctl(first, second, ptr);
2783
        break;
2784

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

    
2794
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2795
                    ret = -TARGET_EFAULT;
2796
                    break;
2797
                }
2798

    
2799
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2800

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

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

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

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

    
2848
/* kernel structure types definitions */
2849
#define IFNAMSIZ        16
2850

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

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

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

    
2873
#define IOC_R 0x0001
2874
#define IOC_W 0x0002
2875
#define IOC_RW (IOC_R | IOC_W)
2876

    
2877
#define MAX_STRUCT_SIZE 4096
2878

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

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

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

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

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

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

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

    
3070
static void target_to_host_termios (void *dst, const void *src)
3071
{
3072
    struct host_termios *host = dst;
3073
    const struct target_termios *target = src;
3074

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

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

    
3105
static void host_to_target_termios (void *dst, const void *src)
3106
{
3107
    struct target_termios *target = dst;
3108
    const struct host_termios *host = src;
3109

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

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

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

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

    
3158
#if defined(TARGET_I386)
3159

    
3160
/* NOTE: there is really one LDT for all the threads */
3161
static uint8_t *ldt_table;
3162

    
3163
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3164
{
3165
    int size;
3166
    void *p;
3167

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

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

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

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

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

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

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

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

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

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

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

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

    
3341
    if (contents == 3) {
3342
        if (seg_not_present == 0)
3343
            return -TARGET_EINVAL;
3344
    }
3345

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

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

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

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

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

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

    
3466
#endif /* defined(TARGET_I386) */
3467

    
3468
#if defined(CONFIG_USE_NPTL)
3469

    
3470
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3471

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

    
3484
static void *clone_func(void *arg)
3485
{
3486
    new_thread_info *info = arg;
3487
    CPUState *env;
3488
    TaskState *ts;
3489

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

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

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

    
3542
    /* Emulate vfork() with fork() */
3543
    if (flags & CLONE_VFORK)
3544
        flags &= ~(CLONE_VFORK | CLONE_VM);
3545

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

    
3569
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3570
            ts->child_tidptr = child_tidptr;
3571
        }
3572

    
3573
        if (nptl_flags & CLONE_SETTLS)
3574
            cpu_set_tls (new_env, newtls);
3575

    
3576
        /* Grab a mutex so that thread setup appears atomic.  */
3577
        pthread_mutex_lock(&clone_lock);
3578

    
3579
        memset(&info, 0, sizeof(info));
3580
        pthread_mutex_init(&info.mutex, NULL);
3581
        pthread_mutex_lock(&info.mutex);
3582
        pthread_cond_init(&info.cond, NULL);
3583
        info.env = new_env;
3584
        if (nptl_flags & CLONE_CHILD_SETTID)
3585
            info.child_tidptr = child_tidptr;
3586
        if (nptl_flags & CLONE_PARENT_SETTID)
3587
            info.parent_tidptr = parent_tidptr;
3588

    
3589
        ret = pthread_attr_init(&attr);
3590
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3591
        /* It is not safe to deliver signals until the child has finished
3592
           initializing, so temporarily block all signals.  */
3593
        sigfillset(&sigmask);
3594
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3595

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

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

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

    
3706
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3707
{
3708
    struct flock fl;
3709
    struct target_flock *target_fl;
3710
    struct flock64 fl64;
3711
    struct target_flock64 *target_fl64;
3712
    abi_long ret;
3713
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3714

    
3715
    if (host_cmd == -TARGET_EINVAL)
3716
            return host_cmd;
3717

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

    
3741
    case TARGET_F_SETLK:
3742
    case TARGET_F_SETLKW:
3743
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3744
            return -TARGET_EFAULT;
3745
        fl.l_type = tswap16(target_fl->l_type);
3746
        fl.l_whence = tswap16(target_fl->l_whence);
3747
        fl.l_start = tswapl(target_fl->l_start);
3748
        fl.l_len = tswapl(target_fl->l_len);
3749
        fl.l_pid = tswap32(target_fl->l_pid);
3750
        unlock_user_struct(target_fl, arg, 0);
3751
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3752
        break;
3753

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

    
3788
    case TARGET_F_GETFL:
3789
        ret = get_errno(fcntl(fd, host_cmd, arg));
3790
        if (ret >= 0) {
3791
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3792
        }
3793
        break;
3794

    
3795
    case TARGET_F_SETFL:
3796
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3797
        break;
3798

    
3799
    case TARGET_F_SETOWN:
3800
    case TARGET_F_GETOWN:
3801
    case TARGET_F_SETSIG:
3802
    case TARGET_F_GETSIG:
3803
    case TARGET_F_SETLEASE:
3804
    case TARGET_F_GETLEASE:
3805
        ret = get_errno(fcntl(fd, host_cmd, arg));
3806
        break;
3807

    
3808
    default:
3809
        ret = get_errno(fcntl(fd, cmd, arg));
3810
        break;
3811
    }
3812
    return ret;
3813
}
3814

    
3815
#ifdef USE_UID16
3816

    
3817
static inline int high2lowuid(int uid)
3818
{
3819
    if (uid > 65535)
3820
        return 65534;
3821
    else
3822
        return uid;
3823
}
3824

    
3825
static inline int high2lowgid(int gid)
3826
{
3827
    if (gid > 65535)
3828
        return 65534;
3829
    else
3830
        return gid;
3831
}
3832

    
3833
static inline int low2highuid(int uid)
3834
{
3835
    if ((int16_t)uid == -1)
3836
        return -1;
3837
    else
3838
        return uid;
3839
}
3840

    
3841
static inline int low2highgid(int gid)
3842
{
3843
    if ((int16_t)gid == -1)
3844
        return -1;
3845
    else
3846
        return gid;
3847
}
3848

    
3849
#endif /* USE_UID16 */
3850

    
3851
void syscall_init(void)
3852
{
3853
    IOCTLEntry *ie;
3854
    const argtype *arg_type;
3855
    int size;
3856
    int i;
3857

    
3858
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3859
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3860
#include "syscall_types.h"
3861
#undef STRUCT
3862
#undef STRUCT_SPECIAL
3863

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

    
3883
        /* Build target_to_host_errno_table[] table from
3884
         * host_to_target_errno_table[]. */
3885
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3886
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3887

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

    
3900
#if TARGET_ABI_BITS == 32
3901
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3902
{
3903
#ifdef TARGET_WORDS_BIGENDIAN
3904
    return ((uint64_t)word0 << 32) | word1;
3905
#else
3906
    return ((uint64_t)word1 << 32) | word0;
3907
#endif
3908
}
3909
#else /* TARGET_ABI_BITS == 32 */
3910
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3911
{
3912
    return word0;
3913
}
3914
#endif /* TARGET_ABI_BITS != 32 */
3915

    
3916
#ifdef TARGET_NR_truncate64
3917
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3918
                                         abi_long arg2,
3919
                                         abi_long arg3,
3920
                                         abi_long arg4)
3921
{
3922
#ifdef TARGET_ARM
3923
    if (((CPUARMState *)cpu_env)->eabi)
3924
      {
3925
        arg2 = arg3;
3926
        arg3 = arg4;
3927
      }
3928
#endif
3929
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3930
}
3931
#endif
3932

    
3933
#ifdef TARGET_NR_ftruncate64
3934
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3935
                                          abi_long arg2,
3936
                                          abi_long arg3,
3937
                                          abi_long arg4)
3938
{
3939
#ifdef TARGET_ARM
3940
    if (((CPUARMState *)cpu_env)->eabi)
3941
      {
3942
        arg2 = arg3;
3943
        arg3 = arg4;
3944
      }
3945
#endif
3946
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3947
}
3948
#endif
3949

    
3950
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3951
                                               abi_ulong target_addr)
3952
{
3953
    struct target_timespec *target_ts;
3954

    
3955
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3956
        return -TARGET_EFAULT;
3957
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3958
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3959
    unlock_user_struct(target_ts, target_addr, 0);
3960
    return 0;
3961
}
3962

    
3963
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3964
                                               struct timespec *host_ts)
3965
{
3966
    struct target_timespec *target_ts;
3967

    
3968
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3969
        return -TARGET_EFAULT;
3970
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3971
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3972
    unlock_user_struct(target_ts, target_addr, 1);
3973
    return 0;
3974
}
3975

    
3976
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3977
static inline abi_long host_to_target_stat64(void *cpu_env,
3978
                                             abi_ulong target_addr,
3979
                                             struct stat *host_st)
3980
{
3981
#ifdef TARGET_ARM
3982
    if (((CPUARMState *)cpu_env)->eabi) {
3983
        struct target_eabi_stat64 *target_st;
3984

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

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

    
4037
    return 0;
4038
}
4039
#endif
4040

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

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

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

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

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

    
4151
#ifdef DEBUG
4152
    gemu_log("syscall %d", num);
4153
#endif
4154
    if(do_strace)
4155
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4156

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

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

    
4334
            argc = 0;
4335
            guest_argp = arg2;
4336
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4337
                if (get_user_ual(addr, gp))
4338
                    goto efault;
4339
                if (!addr)
4340
                    break;
4341
                argc++;
4342
            }
4343
            envc = 0;
4344
            guest_envp = arg3;
4345
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4346
                if (get_user_ual(addr, gp))
4347
                    goto efault;
4348
                if (!addr)
4349
                    break;
4350
                envc++;
4351
            }
4352

    
4353
            argp = alloca((argc + 1) * sizeof(void *));
4354
            envp = alloca((envc + 1) * sizeof(void *));
4355

    
4356
            for (gp = guest_argp, q = argp; gp;
4357
                  gp += sizeof(abi_ulong), q++) {
4358
                if (get_user_ual(addr, gp))
4359
                    goto execve_efault;
4360
                if (!addr)
4361
                    break;
4362
                if (!(*q = lock_user_string(addr)))
4363
                    goto execve_efault;
4364
            }
4365
            *q = NULL;
4366

    
4367
            for (gp = guest_envp, q = envp; gp;
4368
                  gp += sizeof(abi_ulong), q++) {
4369
                if (get_user_ual(addr, gp))
4370
                    goto execve_efault;
4371
                if (!addr)
4372
                    break;
4373
                if (!(*q = lock_user_string(addr)))
4374
                    goto execve_efault;
4375
            }
4376
            *q = NULL;
4377

    
4378
            if (!(p = lock_user_string(arg1)))
4379
                goto execve_efault;
4380
            ret = get_errno(execve(p, argp, envp));
4381
            unlock_user(p, arg1, 0);
4382

    
4383
            goto execve_end;
4384

    
4385
        execve_efault:
4386
            ret = -TARGET_EFAULT;
4387

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

    
4806
            if (arg2) {
4807
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4808
                    goto efault;
4809
                act._sa_handler = old_act->_sa_handler;
4810
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4811
                act.sa_flags = old_act->sa_flags;
4812
                unlock_user_struct(old_act, arg2, 0);
4813
                pact = &act;
4814
            } else {
4815
                pact = NULL;
4816
            }
4817

    
4818
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4819

    
4820
            if (!is_error(ret) && arg3) {
4821
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4822
                    goto efault;
4823
                old_act->_sa_handler = oact._sa_handler;
4824
                old_act->sa_flags = oact.sa_flags;
4825
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4826
                old_act->sa_mask.sig[1] = 0;
4827
                old_act->sa_mask.sig[2] = 0;
4828
                old_act->sa_mask.sig[3] = 0;
4829
                unlock_user_struct(old_act, arg3, 1);
4830
            }
4831
#endif
4832
        }
4833
        break;
4834
#endif
4835
    case TARGET_NR_rt_sigaction:
4836
        {
4837
            struct target_sigaction *act;
4838
            struct target_sigaction *oact;
4839

    
4840
            if (arg2) {
4841
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4842
                    goto efault;
4843
            } else
4844
                act = NULL;
4845
            if (arg3) {
4846
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4847
                    ret = -TARGET_EFAULT;
4848
                    goto rt_sigaction_fail;
4849
                }
4850
            } else
4851
                oact = NULL;
4852
            ret = get_errno(do_sigaction(arg1, act, oact));
4853
        rt_sigaction_fail:
4854
            if (act)
4855
                unlock_user_struct(act, arg2, 0);
4856
            if (oact)
4857
                unlock_user_struct(oact, arg3, 1);
4858
        }
4859
        break;
4860
#ifdef TARGET_NR_sgetmask /* not on alpha */
4861
    case TARGET_NR_sgetmask:
4862
        {
4863
            sigset_t cur_set;
4864
            abi_ulong target_set;
4865
            sigprocmask(0, NULL, &cur_set);
4866
            host_to_target_old_sigset(&target_set, &cur_set);
4867
            ret = target_set;
4868
        }
4869
        break;
4870
#endif
4871
#ifdef TARGET_NR_ssetmask /* not on alpha */
4872
    case TARGET_NR_ssetmask:
4873
        {
4874
            sigset_t set, oset, cur_set;
4875
            abi_ulong target_set = arg1;
4876
            sigprocmask(0, NULL, &cur_set);
4877
            target_to_host_old_sigset(&set, &target_set);
4878
            sigorset(&set, &set, &cur_set);
4879
            sigprocmask(SIG_SETMASK, &set, &oset);
4880
            host_to_target_old_sigset(&target_set, &oset);
4881
            ret = target_set;
4882
        }
4883
        break;
4884
#endif
4885
#ifdef TARGET_NR_sigprocmask
4886
    case TARGET_NR_sigprocmask:
4887
        {
4888
            int how = arg1;
4889
            sigset_t set, oldset, *set_ptr;
4890

    
4891
            if (arg2) {
4892
                switch(how) {
4893
                case TARGET_SIG_BLOCK:
4894
                    how = SIG_BLOCK;
4895
                    break;
4896
                case TARGET_SIG_UNBLOCK:
4897
                    how = SIG_UNBLOCK;
4898
                    break;
4899
                case TARGET_SIG_SETMASK:
4900
                    how = SIG_SETMASK;
4901
                    break;
4902
                default:
4903
                    ret = -TARGET_EINVAL;
4904
                    goto fail;
4905
                }
4906
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4907
                    goto efault;
4908
                target_to_host_old_sigset(&set, p);
4909
                unlock_user(p, arg2, 0);
4910
                set_ptr = &set;
4911
            } else {
4912
                how = 0;
4913
                set_ptr = NULL;
4914
            }
4915
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4916
            if (!is_error(ret) && arg3) {
4917
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4918
                    goto efault;
4919
                host_to_target_old_sigset(p, &oldset);
4920
                unlock_user(p, arg3, sizeof(target_sigset_t));
4921
            }
4922
        }
4923
        break;
4924
#endif
4925
    case TARGET_NR_rt_sigprocmask:
4926
        {
4927
            int how = arg1;
4928
            sigset_t set, oldset, *set_ptr;
4929

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

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

    
5083
            ret = get_errno(getrlimit(resource, &rlim));
5084
            if (!is_error(ret)) {
5085
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5086
                    goto efault;
5087
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5088
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
5089
                unlock_user_struct(target_rlim, arg2, 1);
5090
            }
5091
        }
5092
        break;
5093
    case TARGET_NR_getrusage:
5094
        {
5095
            struct rusage rusage;
5096
            ret = get_errno(getrusage(arg1, &rusage));
5097
            if (!is_error(ret)) {
5098
                host_to_target_rusage(arg2, &rusage);
5099
            }
5100
        }
5101
        break;
5102
    case TARGET_NR_gettimeofday:
5103
        {
5104
            struct timeval tv;
5105
            ret = get_errno(gettimeofday(&tv, NULL));
5106
            if (!is_error(ret)) {
5107
                if (copy_to_user_timeval(arg1, &tv))
5108
                    goto efault;
5109
            }
5110
        }
5111
        break;
5112
    case TARGET_NR_settimeofday:
5113
        {
5114
            struct timeval tv;
5115
            if (copy_from_user_timeval(&tv, arg1))
5116
                goto efault;
5117
            ret = get_errno(settimeofday(&tv, NULL));
5118
        }
5119
        break;
5120
#ifdef TARGET_NR_select
5121
    case TARGET_NR_select:
5122
        {
5123
            struct target_sel_arg_struct *sel;
5124
            abi_ulong inp, outp, exp, tvp;
5125
            long nsel;
5126

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

    
5342
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5343
                goto efault;
5344
            __put_user(stfs.f_type, &target_stfs->f_type);
5345
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5346
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5347
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5348
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5349
            __put_user(stfs.f_files, &target_stfs->f_files);
5350
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5351
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5352
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5353
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5354
            unlock_user_struct(target_stfs, arg2, 1);
5355
        }
5356
        break;
5357
    case TARGET_NR_fstatfs:
5358
        ret = get_errno(fstatfs(arg1, &stfs));
5359
        goto convert_statfs;
5360
#ifdef TARGET_NR_statfs64
5361
    case TARGET_NR_statfs64:
5362
        if (!(p = lock_user_string(arg1)))
5363
            goto efault;
5364
        ret = get_errno(statfs(path(p), &stfs));
5365
        unlock_user(p, arg1, 0);
5366
    convert_statfs64:
5367
        if (!is_error(ret)) {
5368
            struct target_statfs64 *target_stfs;
5369

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

    
5484
    case TARGET_NR_syslog:
5485
        if (!(p = lock_user_string(arg2)))
5486
            goto efault;
5487
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5488
        unlock_user(p, arg2, 0);
5489
        break;
5490

    
5491
    case TARGET_NR_setitimer:
5492
        {
5493
            struct itimerval value, ovalue, *pvalue;
5494

    
5495
            if (arg2) {
5496
                pvalue = &value;
5497
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5498
                    || copy_from_user_timeval(&pvalue->it_value,
5499
                                              arg2 + sizeof(struct target_timeval)))
5500
                    goto efault;
5501
            } else {
5502
                pvalue = NULL;
5503
            }
5504
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5505
            if (!is_error(ret) && arg3) {
5506
                if (copy_to_user_timeval(arg3,
5507
                                         &ovalue.it_interval)
5508
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5509
                                            &ovalue.it_value))
5510
                    goto efault;
5511
            }
5512
        }
5513
        break;
5514
    case TARGET_NR_getitimer:
5515
        {
5516
            struct itimerval value;
5517

    
5518
            ret = get_errno(getitimer(arg1, &value));
5519
            if (!is_error(ret) && arg2) {
5520
                if (copy_to_user_timeval(arg2,
5521
                                         &value.it_interval)
5522
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5523
                                            &value.it_value))
5524
                    goto efault;
5525
            }
5526
        }
5527
        break;
5528
    case TARGET_NR_stat:
5529
        if (!(p = lock_user_string(arg1)))
5530
            goto efault;
5531
        ret = get_errno(stat(path(p), &st));
5532
        unlock_user(p, arg1, 0);
5533
        goto do_stat;
5534
    case TARGET_NR_lstat:
5535
        if (!(p = lock_user_string(arg1)))
5536
            goto efault;
5537
        ret = get_errno(lstat(path(p), &st));
5538
        unlock_user(p, arg1, 0);
5539
        goto do_stat;
5540
    case TARGET_NR_fstat:
5541
        {
5542
            ret = get_errno(fstat(arg1, &st));
5543
        do_stat:
5544
            if (!is_error(ret)) {
5545
                struct target_stat *target_st;
5546

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

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

    
5820
            dirp = malloc(count);
5821
            if (!dirp) {
5822
                ret = -TARGET_ENOMEM;
5823
                goto fail;
5824
            }
5825

    
5826
            ret = get_errno(sys_getdents(arg1, dirp, count));
5827
            if (!is_error(ret)) {
5828
                struct linux_dirent *de;
5829
                struct target_dirent *tde;
5830
                int len = ret;
5831
                int reclen, treclen;
5832
                int count1, tnamelen;
5833

    
5834
                count1 = 0;
5835
                de = dirp;
5836
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5837
                    goto efault;
5838
                tde = target_dirp;
5839
                while (len > 0) {
5840
                    reclen = de->d_reclen;
5841
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5842
                    tde->d_reclen = tswap16(treclen);
5843
                    tde->d_ino = tswapl(de->d_ino);
5844
                    tde->d_off = tswapl(de->d_off);
5845
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5846
                    if (tnamelen > 256)
5847
                        tnamelen = 256;
5848
                    /* XXX: may not be correct */
5849
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5850
                    de = (struct linux_dirent *)((char *)de + reclen);
5851
                    len -= reclen;
5852
                    tde = (struct target_dirent *)((char *)tde + treclen);
5853
                    count1 += treclen;
5854
                }
5855
                ret = count1;
5856
                unlock_user(target_dirp, arg2, ret);
5857
            }
5858
            free(dirp);
5859
        }
5860
#else
5861
        {
5862
            struct linux_dirent *dirp;
5863
            abi_long count = arg3;
5864

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

    
5930
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5931
            if (!target_pfd)
5932
                goto efault;
5933
            pfd = alloca(sizeof(struct pollfd) * nfds);
5934
            for(i = 0; i < nfds; i++) {
5935
                pfd[i].fd = tswap32(target_pfd[i].fd);
5936
                pfd[i].events = tswap16(target_pfd[i].events);
5937
            }
5938
            ret = get_errno(poll(pfd, nfds, timeout));
5939
            if (!is_error(ret)) {
5940
                for(i = 0; i < nfds; i++) {
5941
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5942
                }
5943
                ret += nfds * (sizeof(struct target_pollfd)
5944
                               - sizeof(struct pollfd));
5945
            }
5946
            unlock_user(target_pfd, arg1, ret);
5947
        }
5948
        break;
5949
#endif
5950
    case TARGET_NR_flock:
5951
        /* NOTE: the flock constant seems to be the same for every
5952
           Linux platform */
5953
        ret = get_errno(flock(arg1, arg2));
5954
        break;
5955
    case TARGET_NR_readv:
5956
        {
5957
            int count = arg3;
5958
            struct iovec *vec;
5959

    
5960
            vec = alloca(count * sizeof(struct iovec));
5961
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5962
                goto efault;
5963
            ret = get_errno(readv(arg1, vec, count));
5964
            unlock_iovec(vec, arg2, count, 1);
5965
        }
5966
        break;
5967
    case TARGET_NR_writev:
5968
        {
5969
            int count = arg3;
5970
            struct iovec *vec;
5971

    
5972
            vec = alloca(count * sizeof(struct iovec));
5973
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5974
                goto efault;
5975
            ret = get_errno(writev(arg1, vec, count));
5976
            unlock_iovec(vec, arg2, count, 0);
5977
        }
5978
        break;
5979
    case TARGET_NR_getsid:
5980
        ret = get_errno(getsid(arg1));
5981
        break;
5982
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5983
    case TARGET_NR_fdatasync:
5984
        ret = get_errno(fdatasync(arg1));
5985
        break;
5986
#endif
5987
    case TARGET_NR__sysctl:
5988
        /* We don't implement this, but ENOTDIR is always a safe
5989
           return value. */
5990
        ret = -TARGET_ENOTDIR;
5991
        break;
5992
    case TARGET_NR_sched_setparam:
5993
        {
5994
            struct sched_param *target_schp;
5995
            struct sched_param schp;
5996

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

    
6271
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6272
            ret = get_errno(getgroups(gidsetsize, grouplist));
6273
            if (gidsetsize == 0)
6274
                break;
6275
            if (!is_error(ret)) {
6276
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6277
                if (!target_grouplist)
6278
                    goto efault;
6279
                for(i = 0;i < ret; i++)
6280
                    target_grouplist[i] = tswap16(grouplist[i]);
6281
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6282
            }
6283
        }
6284
        break;
6285
    case TARGET_NR_setgroups:
6286
        {
6287
            int gidsetsize = arg1;
6288
            uint16_t *target_grouplist;
6289
            gid_t *grouplist;
6290
            int i;
6291

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

    
6377
#ifdef TARGET_NR_lchown32
6378
    case TARGET_NR_lchown32:
6379
        if (!(p = lock_user_string(arg1)))
6380
            goto efault;
6381
        ret = get_errno(lchown(p, arg2, arg3));
6382
        unlock_user(p, arg1, 0);
6383
        break;
6384
#endif
6385
#ifdef TARGET_NR_getuid32
6386
    case TARGET_NR_getuid32:
6387
        ret = get_errno(getuid());
6388
        break;
6389
#endif
6390

    
6391
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6392
   /* Alpha specific */
6393
    case TARGET_NR_getxuid:
6394
         {
6395
            uid_t euid;
6396
            euid=geteuid();
6397
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6398
         }
6399
        ret = get_errno(getuid());
6400
        break;
6401
#endif
6402
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6403
   /* Alpha specific */
6404
    case TARGET_NR_getxgid:
6405
         {
6406
            uid_t egid;
6407
            egid=getegid();
6408
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6409
         }
6410
        ret = get_errno(getgid());
6411
        break;
6412
#endif
6413
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
6414
    /* Alpha specific */
6415
    case TARGET_NR_osf_getsysinfo:
6416
        ret = -TARGET_EOPNOTSUPP;
6417
        switch (arg1) {
6418
          case TARGET_GSI_IEEE_FP_CONTROL:
6419
            {
6420
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
6421

    
6422
                /* Copied from linux ieee_fpcr_to_swcr.  */
6423
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
6424
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
6425
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
6426
                                        | SWCR_TRAP_ENABLE_DZE
6427
                                        | SWCR_TRAP_ENABLE_OVF);
6428
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
6429
                                        | SWCR_TRAP_ENABLE_INE);
6430
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
6431
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
6432

    
6433
                if (put_user_u64 (swcr, arg2))
6434
                        goto efault;
6435
                ret = 0;
6436
            }
6437
            break;
6438

    
6439
          /* case GSI_IEEE_STATE_AT_SIGNAL:
6440
             -- Not implemented in linux kernel.
6441
             case GSI_UACPROC:
6442
             -- Retrieves current unaligned access state; not much used.
6443
             case GSI_PROC_TYPE:
6444
             -- Retrieves implver information; surely not used.
6445
             case GSI_GET_HWRPB:
6446
             -- Grabs a copy of the HWRPB; surely not used.
6447
          */
6448
        }
6449
        break;
6450
#endif
6451
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
6452
    /* Alpha specific */
6453
    case TARGET_NR_osf_setsysinfo:
6454
        ret = -TARGET_EOPNOTSUPP;
6455
        switch (arg1) {
6456
          case TARGET_SSI_IEEE_FP_CONTROL:
6457
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
6458
            {
6459
                uint64_t swcr, fpcr, orig_fpcr;
6460

    
6461
                if (get_user_u64 (swcr, arg2))
6462
                    goto efault;
6463
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6464
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6465

    
6466
                /* Copied from linux ieee_swcr_to_fpcr.  */
6467
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
6468
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
6469
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
6470
                                  | SWCR_TRAP_ENABLE_DZE
6471
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
6472
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
6473
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
6474
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
6475
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
6476

    
6477
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6478
                ret = 0;
6479

    
6480
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6481
                    /* Old exceptions are not signaled.  */
6482
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6483

    
6484
                    /* If any exceptions set by this call, and are unmasked,
6485
                       send a signal.  */
6486
                    /* ??? FIXME */
6487
                }
6488
            }
6489
            break;
6490

    
6491
          /* case SSI_NVPAIRS:
6492
             -- Used with SSIN_UACPROC to enable unaligned accesses.
6493
             case SSI_IEEE_STATE_AT_SIGNAL:
6494
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
6495
             -- Not implemented in linux kernel
6496
          */
6497
        }
6498
        break;
6499
#endif
6500
#ifdef TARGET_NR_osf_sigprocmask
6501
    /* Alpha specific.  */
6502
    case TARGET_NR_osf_sigprocmask:
6503
        {
6504
            abi_ulong mask;
6505
            int how = arg1;
6506
            sigset_t set, oldset;
6507

    
6508
            switch(arg1) {
6509
            case TARGET_SIG_BLOCK:
6510
                how = SIG_BLOCK;
6511
                break;
6512
            case TARGET_SIG_UNBLOCK:
6513
                how = SIG_UNBLOCK;
6514
                break;
6515
            case TARGET_SIG_SETMASK:
6516
                how = SIG_SETMASK;
6517
                break;
6518
            default:
6519
                ret = -TARGET_EINVAL;
6520
                goto fail;
6521
            }
6522
            mask = arg2;
6523
            target_to_host_old_sigset(&set, &mask);
6524
            sigprocmask(arg1, &set, &oldset);
6525
            host_to_target_old_sigset(&mask, &oldset);
6526
            ret = mask;
6527
        }
6528
        break;
6529
#endif
6530

    
6531
#ifdef TARGET_NR_getgid32
6532
    case TARGET_NR_getgid32:
6533
        ret = get_errno(getgid());
6534
        break;
6535
#endif
6536
#ifdef TARGET_NR_geteuid32
6537
    case TARGET_NR_geteuid32:
6538
        ret = get_errno(geteuid());
6539
        break;
6540
#endif
6541
#ifdef TARGET_NR_getegid32
6542
    case TARGET_NR_getegid32:
6543
        ret = get_errno(getegid());
6544
        break;
6545
#endif
6546
#ifdef TARGET_NR_setreuid32
6547
    case TARGET_NR_setreuid32:
6548
        ret = get_errno(setreuid(arg1, arg2));
6549
        break;
6550
#endif
6551
#ifdef TARGET_NR_setregid32
6552
    case TARGET_NR_setregid32:
6553
        ret = get_errno(setregid(arg1, arg2));
6554
        break;
6555
#endif
6556
#ifdef TARGET_NR_getgroups32
6557
    case TARGET_NR_getgroups32:
6558
        {
6559
            int gidsetsize = arg1;
6560
            uint32_t *target_grouplist;
6561
            gid_t *grouplist;
6562
            int i;
6563

    
6564
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6565
            ret = get_errno(getgroups(gidsetsize, grouplist));
6566
            if (gidsetsize == 0)
6567
                break;
6568
            if (!is_error(ret)) {
6569
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6570
                if (!target_grouplist) {
6571
                    ret = -TARGET_EFAULT;
6572
                    goto fail;
6573
                }
6574
                for(i = 0;i < ret; i++)
6575
                    target_grouplist[i] = tswap32(grouplist[i]);
6576
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6577
            }
6578
        }
6579
        break;
6580
#endif
6581
#ifdef TARGET_NR_setgroups32
6582
    case TARGET_NR_setgroups32:
6583
        {
6584
            int gidsetsize = arg1;
6585
            uint32_t *target_grouplist;
6586
            gid_t *grouplist;
6587
            int i;
6588

    
6589
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6590
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6591
            if (!target_grouplist) {
6592
                ret = -TARGET_EFAULT;
6593
                goto fail;
6594
            }
6595
            for(i = 0;i < gidsetsize; i++)
6596
                grouplist[i] = tswap32(target_grouplist[i]);
6597
            unlock_user(target_grouplist, arg2, 0);
6598
            ret = get_errno(setgroups(gidsetsize, grouplist));
6599
        }
6600
        break;
6601
#endif
6602
#ifdef TARGET_NR_fchown32
6603
    case TARGET_NR_fchown32:
6604
        ret = get_errno(fchown(arg1, arg2, arg3));
6605
        break;
6606
#endif
6607
#ifdef TARGET_NR_setresuid32
6608
    case TARGET_NR_setresuid32:
6609
        ret = get_errno(setresuid(arg1, arg2, arg3));
6610
        break;
6611
#endif
6612
#ifdef TARGET_NR_getresuid32
6613
    case TARGET_NR_getresuid32:
6614
        {
6615
            uid_t ruid, euid, suid;
6616
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6617
            if (!is_error(ret)) {
6618
                if (put_user_u32(ruid, arg1)
6619
                    || put_user_u32(euid, arg2)
6620
                    || put_user_u32(suid, arg3))
6621
                    goto efault;
6622
            }
6623
        }
6624
        break;
6625
#endif
6626
#ifdef TARGET_NR_setresgid32
6627
    case TARGET_NR_setresgid32:
6628
        ret = get_errno(setresgid(arg1, arg2, arg3));
6629
        break;
6630
#endif
6631
#ifdef TARGET_NR_getresgid32
6632
    case TARGET_NR_getresgid32:
6633
        {
6634
            gid_t rgid, egid, sgid;
6635
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6636
            if (!is_error(ret)) {
6637
                if (put_user_u32(rgid, arg1)
6638
                    || put_user_u32(egid, arg2)
6639
                    || put_user_u32(sgid, arg3))
6640
                    goto efault;
6641
            }
6642
        }
6643
        break;
6644
#endif
6645
#ifdef TARGET_NR_chown32
6646
    case TARGET_NR_chown32:
6647
        if (!(p = lock_user_string(arg1)))
6648
            goto efault;
6649
        ret = get_errno(chown(p, arg2, arg3));
6650
        unlock_user(p, arg1, 0);
6651
        break;
6652
#endif
6653
#ifdef TARGET_NR_setuid32
6654
    case TARGET_NR_setuid32:
6655
        ret = get_errno(setuid(arg1));
6656
        break;
6657
#endif
6658
#ifdef TARGET_NR_setgid32
6659
    case TARGET_NR_setgid32:
6660
        ret = get_errno(setgid(arg1));
6661
        break;
6662
#endif
6663
#ifdef TARGET_NR_setfsuid32
6664
    case TARGET_NR_setfsuid32:
6665
        ret = get_errno(setfsuid(arg1));
6666
        break;
6667
#endif
6668
#ifdef TARGET_NR_setfsgid32
6669
    case TARGET_NR_setfsgid32:
6670
        ret = get_errno(setfsgid(arg1));
6671
        break;
6672
#endif
6673

    
6674
    case TARGET_NR_pivot_root:
6675
        goto unimplemented;
6676
#ifdef TARGET_NR_mincore
6677
    case TARGET_NR_mincore:
6678
        {
6679
            void *a;
6680
            ret = -TARGET_EFAULT;
6681
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6682
                goto efault;
6683
            if (!(p = lock_user_string(arg3)))
6684
                goto mincore_fail;
6685
            ret = get_errno(mincore(a, arg2, p));
6686
            unlock_user(p, arg3, ret);
6687
            mincore_fail:
6688
            unlock_user(a, arg1, 0);
6689
        }
6690
        break;
6691
#endif
6692
#ifdef TARGET_NR_arm_fadvise64_64
6693
    case TARGET_NR_arm_fadvise64_64:
6694
        {
6695
                /*
6696
                 * arm_fadvise64_64 looks like fadvise64_64 but
6697
                 * with different argument order
6698
                 */
6699
                abi_long temp;
6700
                temp = arg3;
6701
                arg3 = arg4;
6702
                arg4 = temp;
6703
        }
6704
#endif
6705
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
6706
#ifdef TARGET_NR_fadvise64_64
6707
    case TARGET_NR_fadvise64_64:
6708
#endif
6709
#ifdef TARGET_NR_fadvise64
6710
    case TARGET_NR_fadvise64:
6711
#endif
6712
#ifdef TARGET_S390X
6713
        switch (arg4) {
6714
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
6715
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
6716
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
6717
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
6718
        default: break;
6719
        }
6720
#endif
6721
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
6722
        break;
6723
#endif
6724
#ifdef TARGET_NR_madvise
6725
    case TARGET_NR_madvise:
6726
        /* A straight passthrough may not be safe because qemu sometimes
6727
           turns private flie-backed mappings into anonymous mappings.
6728
           This will break MADV_DONTNEED.
6729
           This is a hint, so ignoring and returning success is ok.  */
6730
        ret = get_errno(0);
6731
        break;
6732
#endif
6733
#if TARGET_ABI_BITS == 32
6734
    case TARGET_NR_fcntl64:
6735
    {
6736
        int cmd;
6737
        struct flock64 fl;
6738
        struct target_flock64 *target_fl;
6739
#ifdef TARGET_ARM
6740
        struct target_eabi_flock64 *target_efl;
6741
#endif
6742

    
6743
        cmd = target_to_host_fcntl_cmd(arg2);
6744
        if (cmd == -TARGET_EINVAL)
6745
                return cmd;
6746

    
6747
        switch(arg2) {
6748
        case TARGET_F_GETLK64:
6749
#ifdef TARGET_ARM
6750
            if (((CPUARMState *)cpu_env)->eabi) {
6751
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6752
                    goto efault;
6753
                fl.l_type = tswap16(target_efl->l_type);
6754
                fl.l_whence = tswap16(target_efl->l_whence);
6755
                fl.l_start = tswap64(target_efl->l_start);
6756
                fl.l_len = tswap64(target_efl->l_len);
6757
                fl.l_pid = tswap32(target_efl->l_pid);
6758
                unlock_user_struct(target_efl, arg3, 0);
6759
            } else
6760
#endif
6761
            {
6762
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6763
                    goto efault;
6764
                fl.l_type = tswap16(target_fl->l_type);
6765
                fl.l_whence = tswap16(target_fl->l_whence);
6766
                fl.l_start = tswap64(target_fl->l_start);
6767
                fl.l_len = tswap64(target_fl->l_len);
6768
                fl.l_pid = tswap32(target_fl->l_pid);
6769
                unlock_user_struct(target_fl, arg3, 0);
6770
            }
6771
            ret = get_errno(fcntl(arg1, cmd, &fl));
6772
            if (ret == 0) {
6773
#ifdef TARGET_ARM
6774
                if (((CPUARMState *)cpu_env)->eabi) {
6775
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6776
                        goto efault;
6777
                    target_efl->l_type = tswap16(fl.l_type);
6778
                    target_efl->l_whence = tswap16(fl.l_whence);
6779
                    target_efl->l_start = tswap64(fl.l_start);
6780
                    target_efl->l_len = tswap64(fl.l_len);
6781
                    target_efl->l_pid = tswap32(fl.l_pid);
6782
                    unlock_user_struct(target_efl, arg3, 1);
6783
                } else
6784
#endif
6785
                {
6786
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6787
                        goto efault;
6788
                    target_fl->l_type = tswap16(fl.l_type);
6789
                    target_fl->l_whence = tswap16(fl.l_whence);
6790
                    target_fl->l_start = tswap64(fl.l_start);
6791
                    target_fl->l_len = tswap64(fl.l_len);
6792
                    target_fl->l_pid = tswap32(fl.l_pid);
6793
                    unlock_user_struct(target_fl, arg3, 1);
6794
                }
6795
            }
6796
            break;
6797

    
6798
        case TARGET_F_SETLK64:
6799
        case TARGET_F_SETLKW64:
6800
#ifdef TARGET_ARM
6801
            if (((CPUARMState *)cpu_env)->eabi) {
6802
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6803
                    goto efault;
6804
                fl.l_type = tswap16(target_efl->l_type);
6805
                fl.l_whence = tswap16(target_efl->l_whence);
6806
                fl.l_start = tswap64(target_efl->l_start);
6807
                fl.l_len = tswap64(target_efl->l_len);
6808
                fl.l_pid = tswap32(target_efl->l_pid);
6809
                unlock_user_struct(target_efl, arg3, 0);
6810
            } else
6811
#endif
6812
            {
6813
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6814
                    goto efault;
6815
                fl.l_type = tswap16(target_fl->l_type);
6816
                fl.l_whence = tswap16(target_fl->l_whence);
6817
                fl.l_start = tswap64(target_fl->l_start);
6818
                fl.l_len = tswap64(target_fl->l_len);
6819
                fl.l_pid = tswap32(target_fl->l_pid);
6820
                unlock_user_struct(target_fl, arg3, 0);
6821
            }
6822
            ret = get_errno(fcntl(arg1, cmd, &fl));
6823
            break;
6824
        default:
6825
            ret = do_fcntl(arg1, arg2, arg3);
6826
            break;
6827
        }
6828
        break;
6829
    }
6830
#endif
6831
#ifdef TARGET_NR_cacheflush
6832
    case TARGET_NR_cacheflush:
6833
        /* self-modifying code is handled automatically, so nothing needed */
6834
        ret = 0;
6835
        break;
6836
#endif
6837
#ifdef TARGET_NR_security
6838
    case TARGET_NR_security:
6839
        goto unimplemented;
6840
#endif
6841
#ifdef TARGET_NR_getpagesize
6842
    case TARGET_NR_getpagesize:
6843
        ret = TARGET_PAGE_SIZE;
6844
        break;
6845
#endif
6846
    case TARGET_NR_gettid:
6847
        ret = get_errno(gettid());
6848
        break;
6849
#ifdef TARGET_NR_readahead
6850
    case TARGET_NR_readahead:
6851
#if TARGET_ABI_BITS == 32
6852
#ifdef TARGET_ARM
6853
        if (((CPUARMState *)cpu_env)->eabi)
6854
        {
6855
            arg2 = arg3;
6856
            arg3 = arg4;
6857
            arg4 = arg5;
6858
        }
6859
#endif
6860
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6861
#else
6862
        ret = get_errno(readahead(arg1, arg2, arg3));
6863
#endif
6864
        break;
6865
#endif
6866
#ifdef TARGET_NR_setxattr
6867
    case TARGET_NR_setxattr:
6868
    case TARGET_NR_lsetxattr:
6869
    case TARGET_NR_fsetxattr:
6870
    case TARGET_NR_getxattr:
6871
    case TARGET_NR_lgetxattr:
6872
    case TARGET_NR_fgetxattr:
6873
    case TARGET_NR_listxattr:
6874
    case TARGET_NR_llistxattr:
6875
    case TARGET_NR_flistxattr:
6876
    case TARGET_NR_removexattr:
6877
    case TARGET_NR_lremovexattr:
6878
    case TARGET_NR_fremovexattr:
6879
        ret = -TARGET_EOPNOTSUPP;
6880
        break;
6881
#endif
6882
#ifdef TARGET_NR_set_thread_area
6883
    case TARGET_NR_set_thread_area:
6884
#if defined(TARGET_MIPS)
6885
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6886
      ret = 0;
6887
      break;
6888
#elif defined(TARGET_CRIS)
6889
      if (arg1 & 0xff)
6890
          ret = -TARGET_EINVAL;
6891
      else {
6892
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6893
          ret = 0;
6894
      }
6895
      break;
6896
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6897
      ret = do_set_thread_area(cpu_env, arg1);
6898
      break;
6899
#else
6900
      goto unimplemented_nowarn;
6901
#endif
6902
#endif
6903
#ifdef TARGET_NR_get_thread_area
6904
    case TARGET_NR_get_thread_area:
6905
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6906
        ret = do_get_thread_area(cpu_env, arg1);
6907
#else
6908
        goto unimplemented_nowarn;
6909
#endif
6910
#endif
6911
#ifdef TARGET_NR_getdomainname
6912
    case TARGET_NR_getdomainname:
6913
        goto unimplemented_nowarn;
6914
#endif
6915

    
6916
#ifdef TARGET_NR_clock_gettime
6917
    case TARGET_NR_clock_gettime:
6918
    {
6919
        struct timespec ts;
6920
        ret = get_errno(clock_gettime(arg1, &ts));
6921
        if (!is_error(ret)) {
6922
            host_to_target_timespec(arg2, &ts);
6923
        }
6924
        break;
6925
    }
6926
#endif
6927
#ifdef TARGET_NR_clock_getres
6928
    case TARGET_NR_clock_getres:
6929
    {
6930
        struct timespec ts;
6931
        ret = get_errno(clock_getres(arg1, &ts));
6932
        if (!is_error(ret)) {
6933
            host_to_target_timespec(arg2, &ts);
6934
        }
6935
        break;
6936
    }
6937
#endif
6938
#ifdef TARGET_NR_clock_nanosleep
6939
    case TARGET_NR_clock_nanosleep:
6940
    {
6941
        struct timespec ts;
6942
        target_to_host_timespec(&ts, arg3);
6943
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6944
        if (arg4)
6945
            host_to_target_timespec(arg4, &ts);
6946
        break;
6947
    }
6948
#endif
6949

    
6950
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6951
    case TARGET_NR_set_tid_address:
6952
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6953
        break;
6954
#endif
6955

    
6956
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6957
    case TARGET_NR_tkill:
6958
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6959
        break;
6960
#endif
6961

    
6962
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6963
    case TARGET_NR_tgkill:
6964
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6965
                        target_to_host_signal(arg3)));
6966
        break;
6967
#endif
6968

    
6969
#ifdef TARGET_NR_set_robust_list
6970
    case TARGET_NR_set_robust_list:
6971
        goto unimplemented_nowarn;
6972
#endif
6973

    
6974
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6975
    case TARGET_NR_utimensat:
6976
        {
6977
            struct timespec *tsp, ts[2];
6978
            if (!arg3) {
6979
                tsp = NULL;
6980
            } else {
6981
                target_to_host_timespec(ts, arg3);
6982
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6983
                tsp = ts;
6984
            }
6985
            if (!arg2)
6986
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6987
            else {
6988
                if (!(p = lock_user_string(arg2))) {
6989
                    ret = -TARGET_EFAULT;
6990
                    goto fail;
6991
                }
6992
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6993
                unlock_user(p, arg2, 0);
6994
            }
6995
        }
6996
        break;
6997
#endif
6998
#if defined(CONFIG_USE_NPTL)
6999
    case TARGET_NR_futex:
7000
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7001
        break;
7002
#endif
7003
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7004
    case TARGET_NR_inotify_init:
7005
        ret = get_errno(sys_inotify_init());
7006
        break;
7007
#endif
7008
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7009
    case TARGET_NR_inotify_add_watch:
7010
        p = lock_user_string(arg2);
7011
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7012
        unlock_user(p, arg2, 0);
7013
        break;
7014
#endif
7015
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7016
    case TARGET_NR_inotify_rm_watch:
7017
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7018
        break;
7019
#endif
7020

    
7021
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7022
    case TARGET_NR_mq_open:
7023
        {
7024
            struct mq_attr posix_mq_attr;
7025

    
7026
            p = lock_user_string(arg1 - 1);
7027
            if (arg4 != 0)
7028
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7029
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7030
            unlock_user (p, arg1, 0);
7031
        }
7032
        break;
7033

    
7034
    case TARGET_NR_mq_unlink:
7035
        p = lock_user_string(arg1 - 1);
7036
        ret = get_errno(mq_unlink(p));
7037
        unlock_user (p, arg1, 0);
7038
        break;
7039

    
7040
    case TARGET_NR_mq_timedsend:
7041
        {
7042
            struct timespec ts;
7043

    
7044
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7045
            if (arg5 != 0) {
7046
                target_to_host_timespec(&ts, arg5);
7047
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7048
                host_to_target_timespec(arg5, &ts);
7049
            }
7050
            else
7051
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7052
            unlock_user (p, arg2, arg3);
7053
        }
7054
        break;
7055

    
7056
    case TARGET_NR_mq_timedreceive:
7057
        {
7058
            struct timespec ts;
7059
            unsigned int prio;
7060

    
7061
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7062
            if (arg5 != 0) {
7063
                target_to_host_timespec(&ts, arg5);
7064
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7065
                host_to_target_timespec(arg5, &ts);
7066
            }
7067
            else
7068
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7069
            unlock_user (p, arg2, arg3);
7070
            if (arg4 != 0)
7071
                put_user_u32(prio, arg4);
7072
        }
7073
        break;
7074

    
7075
    /* Not implemented for now... */
7076
/*     case TARGET_NR_mq_notify: */
7077
/*         break; */
7078

    
7079
    case TARGET_NR_mq_getsetattr:
7080
        {
7081
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7082
            ret = 0;
7083
            if (arg3 != 0) {
7084
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7085
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7086
            }
7087
            if (arg2 != 0) {
7088
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7089
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7090
            }
7091

    
7092
        }
7093
        break;
7094
#endif
7095

    
7096
#ifdef CONFIG_SPLICE
7097
#ifdef TARGET_NR_tee
7098
    case TARGET_NR_tee:
7099
        {
7100
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7101
        }
7102
        break;
7103
#endif
7104
#ifdef TARGET_NR_splice
7105
    case TARGET_NR_splice:
7106
        {
7107
            loff_t loff_in, loff_out;
7108
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7109
            if(arg2) {
7110
                get_user_u64(loff_in, arg2);
7111
                ploff_in = &loff_in;
7112
            }
7113
            if(arg4) {
7114
                get_user_u64(loff_out, arg2);
7115
                ploff_out = &loff_out;
7116
            }
7117
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7118
        }
7119
        break;
7120
#endif
7121
#ifdef TARGET_NR_vmsplice
7122
        case TARGET_NR_vmsplice:
7123
        {
7124
            int count = arg3;
7125
            struct iovec *vec;
7126

    
7127
            vec = alloca(count * sizeof(struct iovec));
7128
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7129
                goto efault;
7130
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7131
            unlock_iovec(vec, arg2, count, 0);
7132
        }
7133
        break;
7134
#endif
7135
#endif /* CONFIG_SPLICE */
7136
#ifdef CONFIG_EVENTFD
7137
#if defined(TARGET_NR_eventfd)
7138
    case TARGET_NR_eventfd:
7139
        ret = get_errno(eventfd(arg1, 0));
7140
        break;
7141
#endif
7142
#if defined(TARGET_NR_eventfd2)
7143
    case TARGET_NR_eventfd2:
7144
        ret = get_errno(eventfd(arg1, arg2));
7145
        break;
7146
#endif
7147
#endif /* CONFIG_EVENTFD  */
7148
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7149
    case TARGET_NR_fallocate:
7150
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7151
        break;
7152
#endif
7153
    default:
7154
    unimplemented:
7155
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7156
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7157
    unimplemented_nowarn:
7158
#endif
7159
        ret = -TARGET_ENOSYS;
7160
        break;
7161
    }
7162
fail:
7163
#ifdef DEBUG
7164
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7165
#endif
7166
    if(do_strace)
7167
        print_syscall_ret(num, ret);
7168
    return ret;
7169
efault:
7170
    ret = -TARGET_EFAULT;
7171
    goto fail;
7172
}