Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 6049f4f8

History | View | Annotate | Download (221.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_ALPHA)
4779
            struct target_sigaction act, oact, *pact = 0;
4780
            struct target_old_sigaction *old_act;
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 = 0;
4788
                unlock_user_struct(old_act, arg2, 0);
4789
                pact = &act;
4790
            }
4791
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4792
            if (!is_error(ret) && arg3) {
4793
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4794
                    goto efault;
4795
                old_act->_sa_handler = oact._sa_handler;
4796
                old_act->sa_mask = oact.sa_mask.sig[0];
4797
                old_act->sa_flags = oact.sa_flags;
4798
                unlock_user_struct(old_act, arg3, 1);
4799
            }
4800
#elif defined(TARGET_MIPS)
4801
            struct target_sigaction act, oact, *pact, *old_act;
4802

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

    
4815
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4816

    
4817
            if (!is_error(ret) && arg3) {
4818
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4819
                    goto efault;
4820
                old_act->_sa_handler = oact._sa_handler;
4821
                old_act->sa_flags = oact.sa_flags;
4822
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4823
                old_act->sa_mask.sig[1] = 0;
4824
                old_act->sa_mask.sig[2] = 0;
4825
                old_act->sa_mask.sig[3] = 0;
4826
                unlock_user_struct(old_act, arg3, 1);
4827
            }
4828
#else
4829
            struct target_old_sigaction *old_act;
4830
            struct target_sigaction act, oact, *pact;
4831
            if (arg2) {
4832
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4833
                    goto efault;
4834
                act._sa_handler = old_act->_sa_handler;
4835
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4836
                act.sa_flags = old_act->sa_flags;
4837
                act.sa_restorer = old_act->sa_restorer;
4838
                unlock_user_struct(old_act, arg2, 0);
4839
                pact = &act;
4840
            } else {
4841
                pact = NULL;
4842
            }
4843
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4844
            if (!is_error(ret) && arg3) {
4845
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4846
                    goto efault;
4847
                old_act->_sa_handler = oact._sa_handler;
4848
                old_act->sa_mask = oact.sa_mask.sig[0];
4849
                old_act->sa_flags = oact.sa_flags;
4850
                old_act->sa_restorer = oact.sa_restorer;
4851
                unlock_user_struct(old_act, arg3, 1);
4852
            }
4853
#endif
4854
        }
4855
        break;
4856
#endif
4857
    case TARGET_NR_rt_sigaction:
4858
        {
4859
#if defined(TARGET_ALPHA)
4860
            struct target_sigaction act, oact, *pact = 0;
4861
            struct target_rt_sigaction *rt_act;
4862
            /* ??? arg4 == sizeof(sigset_t).  */
4863
            if (arg2) {
4864
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
4865
                    goto efault;
4866
                act._sa_handler = rt_act->_sa_handler;
4867
                act.sa_mask = rt_act->sa_mask;
4868
                act.sa_flags = rt_act->sa_flags;
4869
                act.sa_restorer = arg5;
4870
                unlock_user_struct(rt_act, arg2, 0);
4871
                pact = &act;
4872
            }
4873
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4874
            if (!is_error(ret) && arg3) {
4875
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
4876
                    goto efault;
4877
                rt_act->_sa_handler = oact._sa_handler;
4878
                rt_act->sa_mask = oact.sa_mask;
4879
                rt_act->sa_flags = oact.sa_flags;
4880
                unlock_user_struct(rt_act, arg3, 1);
4881
            }
4882
#else
4883
            struct target_sigaction *act;
4884
            struct target_sigaction *oact;
4885

    
4886
            if (arg2) {
4887
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4888
                    goto efault;
4889
            } else
4890
                act = NULL;
4891
            if (arg3) {
4892
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4893
                    ret = -TARGET_EFAULT;
4894
                    goto rt_sigaction_fail;
4895
                }
4896
            } else
4897
                oact = NULL;
4898
            ret = get_errno(do_sigaction(arg1, act, oact));
4899
        rt_sigaction_fail:
4900
            if (act)
4901
                unlock_user_struct(act, arg2, 0);
4902
            if (oact)
4903
                unlock_user_struct(oact, arg3, 1);
4904
#endif
4905
        }
4906
        break;
4907
#ifdef TARGET_NR_sgetmask /* not on alpha */
4908
    case TARGET_NR_sgetmask:
4909
        {
4910
            sigset_t cur_set;
4911
            abi_ulong target_set;
4912
            sigprocmask(0, NULL, &cur_set);
4913
            host_to_target_old_sigset(&target_set, &cur_set);
4914
            ret = target_set;
4915
        }
4916
        break;
4917
#endif
4918
#ifdef TARGET_NR_ssetmask /* not on alpha */
4919
    case TARGET_NR_ssetmask:
4920
        {
4921
            sigset_t set, oset, cur_set;
4922
            abi_ulong target_set = arg1;
4923
            sigprocmask(0, NULL, &cur_set);
4924
            target_to_host_old_sigset(&set, &target_set);
4925
            sigorset(&set, &set, &cur_set);
4926
            sigprocmask(SIG_SETMASK, &set, &oset);
4927
            host_to_target_old_sigset(&target_set, &oset);
4928
            ret = target_set;
4929
        }
4930
        break;
4931
#endif
4932
#ifdef TARGET_NR_sigprocmask
4933
    case TARGET_NR_sigprocmask:
4934
        {
4935
            int how = arg1;
4936
            sigset_t set, oldset, *set_ptr;
4937

    
4938
            if (arg2) {
4939
                switch(how) {
4940
                case TARGET_SIG_BLOCK:
4941
                    how = SIG_BLOCK;
4942
                    break;
4943
                case TARGET_SIG_UNBLOCK:
4944
                    how = SIG_UNBLOCK;
4945
                    break;
4946
                case TARGET_SIG_SETMASK:
4947
                    how = SIG_SETMASK;
4948
                    break;
4949
                default:
4950
                    ret = -TARGET_EINVAL;
4951
                    goto fail;
4952
                }
4953
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4954
                    goto efault;
4955
                target_to_host_old_sigset(&set, p);
4956
                unlock_user(p, arg2, 0);
4957
                set_ptr = &set;
4958
            } else {
4959
                how = 0;
4960
                set_ptr = NULL;
4961
            }
4962
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4963
            if (!is_error(ret) && arg3) {
4964
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4965
                    goto efault;
4966
                host_to_target_old_sigset(p, &oldset);
4967
                unlock_user(p, arg3, sizeof(target_sigset_t));
4968
            }
4969
        }
4970
        break;
4971
#endif
4972
    case TARGET_NR_rt_sigprocmask:
4973
        {
4974
            int how = arg1;
4975
            sigset_t set, oldset, *set_ptr;
4976

    
4977
            if (arg2) {
4978
                switch(how) {
4979
                case TARGET_SIG_BLOCK:
4980
                    how = SIG_BLOCK;
4981
                    break;
4982
                case TARGET_SIG_UNBLOCK:
4983
                    how = SIG_UNBLOCK;
4984
                    break;
4985
                case TARGET_SIG_SETMASK:
4986
                    how = SIG_SETMASK;
4987
                    break;
4988
                default:
4989
                    ret = -TARGET_EINVAL;
4990
                    goto fail;
4991
                }
4992
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4993
                    goto efault;
4994
                target_to_host_sigset(&set, p);
4995
                unlock_user(p, arg2, 0);
4996
                set_ptr = &set;
4997
            } else {
4998
                how = 0;
4999
                set_ptr = NULL;
5000
            }
5001
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5002
            if (!is_error(ret) && arg3) {
5003
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5004
                    goto efault;
5005
                host_to_target_sigset(p, &oldset);
5006
                unlock_user(p, arg3, sizeof(target_sigset_t));
5007
            }
5008
        }
5009
        break;
5010
#ifdef TARGET_NR_sigpending
5011
    case TARGET_NR_sigpending:
5012
        {
5013
            sigset_t set;
5014
            ret = get_errno(sigpending(&set));
5015
            if (!is_error(ret)) {
5016
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5017
                    goto efault;
5018
                host_to_target_old_sigset(p, &set);
5019
                unlock_user(p, arg1, sizeof(target_sigset_t));
5020
            }
5021
        }
5022
        break;
5023
#endif
5024
    case TARGET_NR_rt_sigpending:
5025
        {
5026
            sigset_t set;
5027
            ret = get_errno(sigpending(&set));
5028
            if (!is_error(ret)) {
5029
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5030
                    goto efault;
5031
                host_to_target_sigset(p, &set);
5032
                unlock_user(p, arg1, sizeof(target_sigset_t));
5033
            }
5034
        }
5035
        break;
5036
#ifdef TARGET_NR_sigsuspend
5037
    case TARGET_NR_sigsuspend:
5038
        {
5039
            sigset_t set;
5040
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5041
                goto efault;
5042
            target_to_host_old_sigset(&set, p);
5043
            unlock_user(p, arg1, 0);
5044
            ret = get_errno(sigsuspend(&set));
5045
        }
5046
        break;
5047
#endif
5048
    case TARGET_NR_rt_sigsuspend:
5049
        {
5050
            sigset_t set;
5051
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5052
                goto efault;
5053
            target_to_host_sigset(&set, p);
5054
            unlock_user(p, arg1, 0);
5055
            ret = get_errno(sigsuspend(&set));
5056
        }
5057
        break;
5058
    case TARGET_NR_rt_sigtimedwait:
5059
        {
5060
            sigset_t set;
5061
            struct timespec uts, *puts;
5062
            siginfo_t uinfo;
5063

    
5064
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5065
                goto efault;
5066
            target_to_host_sigset(&set, p);
5067
            unlock_user(p, arg1, 0);
5068
            if (arg3) {
5069
                puts = &uts;
5070
                target_to_host_timespec(puts, arg3);
5071
            } else {
5072
                puts = NULL;
5073
            }
5074
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5075
            if (!is_error(ret) && arg2) {
5076
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5077
                    goto efault;
5078
                host_to_target_siginfo(p, &uinfo);
5079
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5080
            }
5081
        }
5082
        break;
5083
    case TARGET_NR_rt_sigqueueinfo:
5084
        {
5085
            siginfo_t uinfo;
5086
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5087
                goto efault;
5088
            target_to_host_siginfo(&uinfo, p);
5089
            unlock_user(p, arg1, 0);
5090
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5091
        }
5092
        break;
5093
#ifdef TARGET_NR_sigreturn
5094
    case TARGET_NR_sigreturn:
5095
        /* NOTE: ret is eax, so not transcoding must be done */
5096
        ret = do_sigreturn(cpu_env);
5097
        break;
5098
#endif
5099
    case TARGET_NR_rt_sigreturn:
5100
        /* NOTE: ret is eax, so not transcoding must be done */
5101
        ret = do_rt_sigreturn(cpu_env);
5102
        break;
5103
    case TARGET_NR_sethostname:
5104
        if (!(p = lock_user_string(arg1)))
5105
            goto efault;
5106
        ret = get_errno(sethostname(p, arg2));
5107
        unlock_user(p, arg1, 0);
5108
        break;
5109
    case TARGET_NR_setrlimit:
5110
        {
5111
            /* XXX: convert resource ? */
5112
            int resource = arg1;
5113
            struct target_rlimit *target_rlim;
5114
            struct rlimit rlim;
5115
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5116
                goto efault;
5117
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5118
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
5119
            unlock_user_struct(target_rlim, arg2, 0);
5120
            ret = get_errno(setrlimit(resource, &rlim));
5121
        }
5122
        break;
5123
    case TARGET_NR_getrlimit:
5124
        {
5125
            /* XXX: convert resource ? */
5126
            int resource = arg1;
5127
            struct target_rlimit *target_rlim;
5128
            struct rlimit rlim;
5129

    
5130
            ret = get_errno(getrlimit(resource, &rlim));
5131
            if (!is_error(ret)) {
5132
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5133
                    goto efault;
5134
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5135
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
5136
                unlock_user_struct(target_rlim, arg2, 1);
5137
            }
5138
        }
5139
        break;
5140
    case TARGET_NR_getrusage:
5141
        {
5142
            struct rusage rusage;
5143
            ret = get_errno(getrusage(arg1, &rusage));
5144
            if (!is_error(ret)) {
5145
                host_to_target_rusage(arg2, &rusage);
5146
            }
5147
        }
5148
        break;
5149
    case TARGET_NR_gettimeofday:
5150
        {
5151
            struct timeval tv;
5152
            ret = get_errno(gettimeofday(&tv, NULL));
5153
            if (!is_error(ret)) {
5154
                if (copy_to_user_timeval(arg1, &tv))
5155
                    goto efault;
5156
            }
5157
        }
5158
        break;
5159
    case TARGET_NR_settimeofday:
5160
        {
5161
            struct timeval tv;
5162
            if (copy_from_user_timeval(&tv, arg1))
5163
                goto efault;
5164
            ret = get_errno(settimeofday(&tv, NULL));
5165
        }
5166
        break;
5167
#ifdef TARGET_NR_select
5168
    case TARGET_NR_select:
5169
        {
5170
            struct target_sel_arg_struct *sel;
5171
            abi_ulong inp, outp, exp, tvp;
5172
            long nsel;
5173

    
5174
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5175
                goto efault;
5176
            nsel = tswapl(sel->n);
5177
            inp = tswapl(sel->inp);
5178
            outp = tswapl(sel->outp);
5179
            exp = tswapl(sel->exp);
5180
            tvp = tswapl(sel->tvp);
5181
            unlock_user_struct(sel, arg1, 0);
5182
            ret = do_select(nsel, inp, outp, exp, tvp);
5183
        }
5184
        break;
5185
#endif
5186
    case TARGET_NR_symlink:
5187
        {
5188
            void *p2;
5189
            p = lock_user_string(arg1);
5190
            p2 = lock_user_string(arg2);
5191
            if (!p || !p2)
5192
                ret = -TARGET_EFAULT;
5193
            else
5194
                ret = get_errno(symlink(p, p2));
5195
            unlock_user(p2, arg2, 0);
5196
            unlock_user(p, arg1, 0);
5197
        }
5198
        break;
5199
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5200
    case TARGET_NR_symlinkat:
5201
        {
5202
            void *p2;
5203
            p  = lock_user_string(arg1);
5204
            p2 = lock_user_string(arg3);
5205
            if (!p || !p2)
5206
                ret = -TARGET_EFAULT;
5207
            else
5208
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5209
            unlock_user(p2, arg3, 0);
5210
            unlock_user(p, arg1, 0);
5211
        }
5212
        break;
5213
#endif
5214
#ifdef TARGET_NR_oldlstat
5215
    case TARGET_NR_oldlstat:
5216
        goto unimplemented;
5217
#endif
5218
    case TARGET_NR_readlink:
5219
        {
5220
            void *p2, *temp;
5221
            p = lock_user_string(arg1);
5222
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5223
            if (!p || !p2)
5224
                ret = -TARGET_EFAULT;
5225
            else {
5226
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5227
                    char real[PATH_MAX];
5228
                    temp = realpath(exec_path,real);
5229
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5230
                    snprintf((char *)p2, arg3, "%s", real);
5231
                    }
5232
                else
5233
                    ret = get_errno(readlink(path(p), p2, arg3));
5234
            }
5235
            unlock_user(p2, arg2, ret);
5236
            unlock_user(p, arg1, 0);
5237
        }
5238
        break;
5239
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5240
    case TARGET_NR_readlinkat:
5241
        {
5242
            void *p2;
5243
            p  = lock_user_string(arg2);
5244
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5245
            if (!p || !p2)
5246
                ret = -TARGET_EFAULT;
5247
            else
5248
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5249
            unlock_user(p2, arg3, ret);
5250
            unlock_user(p, arg2, 0);
5251
        }
5252
        break;
5253
#endif
5254
#ifdef TARGET_NR_uselib
5255
    case TARGET_NR_uselib:
5256
        goto unimplemented;
5257
#endif
5258
#ifdef TARGET_NR_swapon
5259
    case TARGET_NR_swapon:
5260
        if (!(p = lock_user_string(arg1)))
5261
            goto efault;
5262
        ret = get_errno(swapon(p, arg2));
5263
        unlock_user(p, arg1, 0);
5264
        break;
5265
#endif
5266
    case TARGET_NR_reboot:
5267
        goto unimplemented;
5268
#ifdef TARGET_NR_readdir
5269
    case TARGET_NR_readdir:
5270
        goto unimplemented;
5271
#endif
5272
#ifdef TARGET_NR_mmap
5273
    case TARGET_NR_mmap:
5274
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5275
        {
5276
            abi_ulong *v;
5277
            abi_ulong v1, v2, v3, v4, v5, v6;
5278
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5279
                goto efault;
5280
            v1 = tswapl(v[0]);
5281
            v2 = tswapl(v[1]);
5282
            v3 = tswapl(v[2]);
5283
            v4 = tswapl(v[3]);
5284
            v5 = tswapl(v[4]);
5285
            v6 = tswapl(v[5]);
5286
            unlock_user(v, arg1, 0);
5287
            ret = get_errno(target_mmap(v1, v2, v3,
5288
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5289
                                        v5, v6));
5290
        }
5291
#else
5292
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5293
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5294
                                    arg5,
5295
                                    arg6));
5296
#endif
5297
        break;
5298
#endif
5299
#ifdef TARGET_NR_mmap2
5300
    case TARGET_NR_mmap2:
5301
#ifndef MMAP_SHIFT
5302
#define MMAP_SHIFT 12
5303
#endif
5304
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5305
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5306
                                    arg5,
5307
                                    arg6 << MMAP_SHIFT));
5308
        break;
5309
#endif
5310
    case TARGET_NR_munmap:
5311
        ret = get_errno(target_munmap(arg1, arg2));
5312
        break;
5313
    case TARGET_NR_mprotect:
5314
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5315
        break;
5316
#ifdef TARGET_NR_mremap
5317
    case TARGET_NR_mremap:
5318
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5319
        break;
5320
#endif
5321
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5322
#ifdef TARGET_NR_msync
5323
    case TARGET_NR_msync:
5324
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5325
        break;
5326
#endif
5327
#ifdef TARGET_NR_mlock
5328
    case TARGET_NR_mlock:
5329
        ret = get_errno(mlock(g2h(arg1), arg2));
5330
        break;
5331
#endif
5332
#ifdef TARGET_NR_munlock
5333
    case TARGET_NR_munlock:
5334
        ret = get_errno(munlock(g2h(arg1), arg2));
5335
        break;
5336
#endif
5337
#ifdef TARGET_NR_mlockall
5338
    case TARGET_NR_mlockall:
5339
        ret = get_errno(mlockall(arg1));
5340
        break;
5341
#endif
5342
#ifdef TARGET_NR_munlockall
5343
    case TARGET_NR_munlockall:
5344
        ret = get_errno(munlockall());
5345
        break;
5346
#endif
5347
    case TARGET_NR_truncate:
5348
        if (!(p = lock_user_string(arg1)))
5349
            goto efault;
5350
        ret = get_errno(truncate(p, arg2));
5351
        unlock_user(p, arg1, 0);
5352
        break;
5353
    case TARGET_NR_ftruncate:
5354
        ret = get_errno(ftruncate(arg1, arg2));
5355
        break;
5356
    case TARGET_NR_fchmod:
5357
        ret = get_errno(fchmod(arg1, arg2));
5358
        break;
5359
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5360
    case TARGET_NR_fchmodat:
5361
        if (!(p = lock_user_string(arg2)))
5362
            goto efault;
5363
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5364
        unlock_user(p, arg2, 0);
5365
        break;
5366
#endif
5367
    case TARGET_NR_getpriority:
5368
        /* libc does special remapping of the return value of
5369
         * sys_getpriority() so it's just easiest to call
5370
         * sys_getpriority() directly rather than through libc. */
5371
        ret = get_errno(sys_getpriority(arg1, arg2));
5372
        break;
5373
    case TARGET_NR_setpriority:
5374
        ret = get_errno(setpriority(arg1, arg2, arg3));
5375
        break;
5376
#ifdef TARGET_NR_profil
5377
    case TARGET_NR_profil:
5378
        goto unimplemented;
5379
#endif
5380
    case TARGET_NR_statfs:
5381
        if (!(p = lock_user_string(arg1)))
5382
            goto efault;
5383
        ret = get_errno(statfs(path(p), &stfs));
5384
        unlock_user(p, arg1, 0);
5385
    convert_statfs:
5386
        if (!is_error(ret)) {
5387
            struct target_statfs *target_stfs;
5388

    
5389
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5390
                goto efault;
5391
            __put_user(stfs.f_type, &target_stfs->f_type);
5392
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5393
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5394
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5395
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5396
            __put_user(stfs.f_files, &target_stfs->f_files);
5397
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5398
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5399
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5400
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5401
            unlock_user_struct(target_stfs, arg2, 1);
5402
        }
5403
        break;
5404
    case TARGET_NR_fstatfs:
5405
        ret = get_errno(fstatfs(arg1, &stfs));
5406
        goto convert_statfs;
5407
#ifdef TARGET_NR_statfs64
5408
    case TARGET_NR_statfs64:
5409
        if (!(p = lock_user_string(arg1)))
5410
            goto efault;
5411
        ret = get_errno(statfs(path(p), &stfs));
5412
        unlock_user(p, arg1, 0);
5413
    convert_statfs64:
5414
        if (!is_error(ret)) {
5415
            struct target_statfs64 *target_stfs;
5416

    
5417
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5418
                goto efault;
5419
            __put_user(stfs.f_type, &target_stfs->f_type);
5420
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5421
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5422
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5423
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5424
            __put_user(stfs.f_files, &target_stfs->f_files);
5425
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5426
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5427
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5428
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5429
            unlock_user_struct(target_stfs, arg3, 1);
5430
        }
5431
        break;
5432
    case TARGET_NR_fstatfs64:
5433
        ret = get_errno(fstatfs(arg1, &stfs));
5434
        goto convert_statfs64;
5435
#endif
5436
#ifdef TARGET_NR_ioperm
5437
    case TARGET_NR_ioperm:
5438
        goto unimplemented;
5439
#endif
5440
#ifdef TARGET_NR_socketcall
5441
    case TARGET_NR_socketcall:
5442
        ret = do_socketcall(arg1, arg2);
5443
        break;
5444
#endif
5445
#ifdef TARGET_NR_accept
5446
    case TARGET_NR_accept:
5447
        ret = do_accept(arg1, arg2, arg3);
5448
        break;
5449
#endif
5450
#ifdef TARGET_NR_bind
5451
    case TARGET_NR_bind:
5452
        ret = do_bind(arg1, arg2, arg3);
5453
        break;
5454
#endif
5455
#ifdef TARGET_NR_connect
5456
    case TARGET_NR_connect:
5457
        ret = do_connect(arg1, arg2, arg3);
5458
        break;
5459
#endif
5460
#ifdef TARGET_NR_getpeername
5461
    case TARGET_NR_getpeername:
5462
        ret = do_getpeername(arg1, arg2, arg3);
5463
        break;
5464
#endif
5465
#ifdef TARGET_NR_getsockname
5466
    case TARGET_NR_getsockname:
5467
        ret = do_getsockname(arg1, arg2, arg3);
5468
        break;
5469
#endif
5470
#ifdef TARGET_NR_getsockopt
5471
    case TARGET_NR_getsockopt:
5472
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5473
        break;
5474
#endif
5475
#ifdef TARGET_NR_listen
5476
    case TARGET_NR_listen:
5477
        ret = get_errno(listen(arg1, arg2));
5478
        break;
5479
#endif
5480
#ifdef TARGET_NR_recv
5481
    case TARGET_NR_recv:
5482
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5483
        break;
5484
#endif
5485
#ifdef TARGET_NR_recvfrom
5486
    case TARGET_NR_recvfrom:
5487
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5488
        break;
5489
#endif
5490
#ifdef TARGET_NR_recvmsg
5491
    case TARGET_NR_recvmsg:
5492
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5493
        break;
5494
#endif
5495
#ifdef TARGET_NR_send
5496
    case TARGET_NR_send:
5497
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5498
        break;
5499
#endif
5500
#ifdef TARGET_NR_sendmsg
5501
    case TARGET_NR_sendmsg:
5502
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5503
        break;
5504
#endif
5505
#ifdef TARGET_NR_sendto
5506
    case TARGET_NR_sendto:
5507
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5508
        break;
5509
#endif
5510
#ifdef TARGET_NR_shutdown
5511
    case TARGET_NR_shutdown:
5512
        ret = get_errno(shutdown(arg1, arg2));
5513
        break;
5514
#endif
5515
#ifdef TARGET_NR_socket
5516
    case TARGET_NR_socket:
5517
        ret = do_socket(arg1, arg2, arg3);
5518
        break;
5519
#endif
5520
#ifdef TARGET_NR_socketpair
5521
    case TARGET_NR_socketpair:
5522
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5523
        break;
5524
#endif
5525
#ifdef TARGET_NR_setsockopt
5526
    case TARGET_NR_setsockopt:
5527
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5528
        break;
5529
#endif
5530

    
5531
    case TARGET_NR_syslog:
5532
        if (!(p = lock_user_string(arg2)))
5533
            goto efault;
5534
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5535
        unlock_user(p, arg2, 0);
5536
        break;
5537

    
5538
    case TARGET_NR_setitimer:
5539
        {
5540
            struct itimerval value, ovalue, *pvalue;
5541

    
5542
            if (arg2) {
5543
                pvalue = &value;
5544
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5545
                    || copy_from_user_timeval(&pvalue->it_value,
5546
                                              arg2 + sizeof(struct target_timeval)))
5547
                    goto efault;
5548
            } else {
5549
                pvalue = NULL;
5550
            }
5551
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5552
            if (!is_error(ret) && arg3) {
5553
                if (copy_to_user_timeval(arg3,
5554
                                         &ovalue.it_interval)
5555
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5556
                                            &ovalue.it_value))
5557
                    goto efault;
5558
            }
5559
        }
5560
        break;
5561
    case TARGET_NR_getitimer:
5562
        {
5563
            struct itimerval value;
5564

    
5565
            ret = get_errno(getitimer(arg1, &value));
5566
            if (!is_error(ret) && arg2) {
5567
                if (copy_to_user_timeval(arg2,
5568
                                         &value.it_interval)
5569
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5570
                                            &value.it_value))
5571
                    goto efault;
5572
            }
5573
        }
5574
        break;
5575
    case TARGET_NR_stat:
5576
        if (!(p = lock_user_string(arg1)))
5577
            goto efault;
5578
        ret = get_errno(stat(path(p), &st));
5579
        unlock_user(p, arg1, 0);
5580
        goto do_stat;
5581
    case TARGET_NR_lstat:
5582
        if (!(p = lock_user_string(arg1)))
5583
            goto efault;
5584
        ret = get_errno(lstat(path(p), &st));
5585
        unlock_user(p, arg1, 0);
5586
        goto do_stat;
5587
    case TARGET_NR_fstat:
5588
        {
5589
            ret = get_errno(fstat(arg1, &st));
5590
        do_stat:
5591
            if (!is_error(ret)) {
5592
                struct target_stat *target_st;
5593

    
5594
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5595
                    goto efault;
5596
                memset(target_st, 0, sizeof(*target_st));
5597
                __put_user(st.st_dev, &target_st->st_dev);
5598
                __put_user(st.st_ino, &target_st->st_ino);
5599
                __put_user(st.st_mode, &target_st->st_mode);
5600
                __put_user(st.st_uid, &target_st->st_uid);
5601
                __put_user(st.st_gid, &target_st->st_gid);
5602
                __put_user(st.st_nlink, &target_st->st_nlink);
5603
                __put_user(st.st_rdev, &target_st->st_rdev);
5604
                __put_user(st.st_size, &target_st->st_size);
5605
                __put_user(st.st_blksize, &target_st->st_blksize);
5606
                __put_user(st.st_blocks, &target_st->st_blocks);
5607
                __put_user(st.st_atime, &target_st->target_st_atime);
5608
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5609
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5610
                unlock_user_struct(target_st, arg2, 1);
5611
            }
5612
        }
5613
        break;
5614
#ifdef TARGET_NR_olduname
5615
    case TARGET_NR_olduname:
5616
        goto unimplemented;
5617
#endif
5618
#ifdef TARGET_NR_iopl
5619
    case TARGET_NR_iopl:
5620
        goto unimplemented;
5621
#endif
5622
    case TARGET_NR_vhangup:
5623
        ret = get_errno(vhangup());
5624
        break;
5625
#ifdef TARGET_NR_idle
5626
    case TARGET_NR_idle:
5627
        goto unimplemented;
5628
#endif
5629
#ifdef TARGET_NR_syscall
5630
    case TARGET_NR_syscall:
5631
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5632
            break;
5633
#endif
5634
    case TARGET_NR_wait4:
5635
        {
5636
            int status;
5637
            abi_long status_ptr = arg2;
5638
            struct rusage rusage, *rusage_ptr;
5639
            abi_ulong target_rusage = arg4;
5640
            if (target_rusage)
5641
                rusage_ptr = &rusage;
5642
            else
5643
                rusage_ptr = NULL;
5644
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5645
            if (!is_error(ret)) {
5646
                if (status_ptr) {
5647
                    status = host_to_target_waitstatus(status);
5648
                    if (put_user_s32(status, status_ptr))
5649
                        goto efault;
5650
                }
5651
                if (target_rusage)
5652
                    host_to_target_rusage(target_rusage, &rusage);
5653
            }
5654
        }
5655
        break;
5656
#ifdef TARGET_NR_swapoff
5657
    case TARGET_NR_swapoff:
5658
        if (!(p = lock_user_string(arg1)))
5659
            goto efault;
5660
        ret = get_errno(swapoff(p));
5661
        unlock_user(p, arg1, 0);
5662
        break;
5663
#endif
5664
    case TARGET_NR_sysinfo:
5665
        {
5666
            struct target_sysinfo *target_value;
5667
            struct sysinfo value;
5668
            ret = get_errno(sysinfo(&value));
5669
            if (!is_error(ret) && arg1)
5670
            {
5671
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5672
                    goto efault;
5673
                __put_user(value.uptime, &target_value->uptime);
5674
                __put_user(value.loads[0], &target_value->loads[0]);
5675
                __put_user(value.loads[1], &target_value->loads[1]);
5676
                __put_user(value.loads[2], &target_value->loads[2]);
5677
                __put_user(value.totalram, &target_value->totalram);
5678
                __put_user(value.freeram, &target_value->freeram);
5679
                __put_user(value.sharedram, &target_value->sharedram);
5680
                __put_user(value.bufferram, &target_value->bufferram);
5681
                __put_user(value.totalswap, &target_value->totalswap);
5682
                __put_user(value.freeswap, &target_value->freeswap);
5683
                __put_user(value.procs, &target_value->procs);
5684
                __put_user(value.totalhigh, &target_value->totalhigh);
5685
                __put_user(value.freehigh, &target_value->freehigh);
5686
                __put_user(value.mem_unit, &target_value->mem_unit);
5687
                unlock_user_struct(target_value, arg1, 1);
5688
            }
5689
        }
5690
        break;
5691
#ifdef TARGET_NR_ipc
5692
    case TARGET_NR_ipc:
5693
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5694
        break;
5695
#endif
5696
#ifdef TARGET_NR_semget
5697
    case TARGET_NR_semget:
5698
        ret = get_errno(semget(arg1, arg2, arg3));
5699
        break;
5700
#endif
5701
#ifdef TARGET_NR_semop
5702
    case TARGET_NR_semop:
5703
        ret = get_errno(do_semop(arg1, arg2, arg3));
5704
        break;
5705
#endif
5706
#ifdef TARGET_NR_semctl
5707
    case TARGET_NR_semctl:
5708
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5709
        break;
5710
#endif
5711
#ifdef TARGET_NR_msgctl
5712
    case TARGET_NR_msgctl:
5713
        ret = do_msgctl(arg1, arg2, arg3);
5714
        break;
5715
#endif
5716
#ifdef TARGET_NR_msgget
5717
    case TARGET_NR_msgget:
5718
        ret = get_errno(msgget(arg1, arg2));
5719
        break;
5720
#endif
5721
#ifdef TARGET_NR_msgrcv
5722
    case TARGET_NR_msgrcv:
5723
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5724
        break;
5725
#endif
5726
#ifdef TARGET_NR_msgsnd
5727
    case TARGET_NR_msgsnd:
5728
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5729
        break;
5730
#endif
5731
#ifdef TARGET_NR_shmget
5732
    case TARGET_NR_shmget:
5733
        ret = get_errno(shmget(arg1, arg2, arg3));
5734
        break;
5735
#endif
5736
#ifdef TARGET_NR_shmctl
5737
    case TARGET_NR_shmctl:
5738
        ret = do_shmctl(arg1, arg2, arg3);
5739
        break;
5740
#endif
5741
#ifdef TARGET_NR_shmat
5742
    case TARGET_NR_shmat:
5743
        ret = do_shmat(arg1, arg2, arg3);
5744
        break;
5745
#endif
5746
#ifdef TARGET_NR_shmdt
5747
    case TARGET_NR_shmdt:
5748
        ret = do_shmdt(arg1);
5749
        break;
5750
#endif
5751
    case TARGET_NR_fsync:
5752
        ret = get_errno(fsync(arg1));
5753
        break;
5754
    case TARGET_NR_clone:
5755
#if defined(TARGET_SH4)
5756
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5757
#elif defined(TARGET_CRIS)
5758
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5759
#else
5760
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5761
#endif
5762
        break;
5763
#ifdef __NR_exit_group
5764
        /* new thread calls */
5765
    case TARGET_NR_exit_group:
5766
#ifdef TARGET_GPROF
5767
        _mcleanup();
5768
#endif
5769
        gdb_exit(cpu_env, arg1);
5770
        ret = get_errno(exit_group(arg1));
5771
        break;
5772
#endif
5773
    case TARGET_NR_setdomainname:
5774
        if (!(p = lock_user_string(arg1)))
5775
            goto efault;
5776
        ret = get_errno(setdomainname(p, arg2));
5777
        unlock_user(p, arg1, 0);
5778
        break;
5779
    case TARGET_NR_uname:
5780
        /* no need to transcode because we use the linux syscall */
5781
        {
5782
            struct new_utsname * buf;
5783

    
5784
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5785
                goto efault;
5786
            ret = get_errno(sys_uname(buf));
5787
            if (!is_error(ret)) {
5788
                /* Overrite the native machine name with whatever is being
5789
                   emulated. */
5790
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
5791
                /* Allow the user to override the reported release.  */
5792
                if (qemu_uname_release && *qemu_uname_release)
5793
                  strcpy (buf->release, qemu_uname_release);
5794
            }
5795
            unlock_user_struct(buf, arg1, 1);
5796
        }
5797
        break;
5798
#ifdef TARGET_I386
5799
    case TARGET_NR_modify_ldt:
5800
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5801
        break;
5802
#if !defined(TARGET_X86_64)
5803
    case TARGET_NR_vm86old:
5804
        goto unimplemented;
5805
    case TARGET_NR_vm86:
5806
        ret = do_vm86(cpu_env, arg1, arg2);
5807
        break;
5808
#endif
5809
#endif
5810
    case TARGET_NR_adjtimex:
5811
        goto unimplemented;
5812
#ifdef TARGET_NR_create_module
5813
    case TARGET_NR_create_module:
5814
#endif
5815
    case TARGET_NR_init_module:
5816
    case TARGET_NR_delete_module:
5817
#ifdef TARGET_NR_get_kernel_syms
5818
    case TARGET_NR_get_kernel_syms:
5819
#endif
5820
        goto unimplemented;
5821
    case TARGET_NR_quotactl:
5822
        goto unimplemented;
5823
    case TARGET_NR_getpgid:
5824
        ret = get_errno(getpgid(arg1));
5825
        break;
5826
    case TARGET_NR_fchdir:
5827
        ret = get_errno(fchdir(arg1));
5828
        break;
5829
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5830
    case TARGET_NR_bdflush:
5831
        goto unimplemented;
5832
#endif
5833
#ifdef TARGET_NR_sysfs
5834
    case TARGET_NR_sysfs:
5835
        goto unimplemented;
5836
#endif
5837
    case TARGET_NR_personality:
5838
        ret = get_errno(personality(arg1));
5839
        break;
5840
#ifdef TARGET_NR_afs_syscall
5841
    case TARGET_NR_afs_syscall:
5842
        goto unimplemented;
5843
#endif
5844
#ifdef TARGET_NR__llseek /* Not on alpha */
5845
    case TARGET_NR__llseek:
5846
        {
5847
#if defined (__x86_64__)
5848
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5849
            if (put_user_s64(ret, arg4))
5850
                goto efault;
5851
#else
5852
            int64_t res;
5853
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5854
            if (put_user_s64(res, arg4))
5855
                goto efault;
5856
#endif
5857
        }
5858
        break;
5859
#endif
5860
    case TARGET_NR_getdents:
5861
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5862
        {
5863
            struct target_dirent *target_dirp;
5864
            struct linux_dirent *dirp;
5865
            abi_long count = arg3;
5866

    
5867
            dirp = malloc(count);
5868
            if (!dirp) {
5869
                ret = -TARGET_ENOMEM;
5870
                goto fail;
5871
            }
5872

    
5873
            ret = get_errno(sys_getdents(arg1, dirp, count));
5874
            if (!is_error(ret)) {
5875
                struct linux_dirent *de;
5876
                struct target_dirent *tde;
5877
                int len = ret;
5878
                int reclen, treclen;
5879
                int count1, tnamelen;
5880

    
5881
                count1 = 0;
5882
                de = dirp;
5883
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5884
                    goto efault;
5885
                tde = target_dirp;
5886
                while (len > 0) {
5887
                    reclen = de->d_reclen;
5888
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5889
                    tde->d_reclen = tswap16(treclen);
5890
                    tde->d_ino = tswapl(de->d_ino);
5891
                    tde->d_off = tswapl(de->d_off);
5892
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5893
                    if (tnamelen > 256)
5894
                        tnamelen = 256;
5895
                    /* XXX: may not be correct */
5896
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5897
                    de = (struct linux_dirent *)((char *)de + reclen);
5898
                    len -= reclen;
5899
                    tde = (struct target_dirent *)((char *)tde + treclen);
5900
                    count1 += treclen;
5901
                }
5902
                ret = count1;
5903
                unlock_user(target_dirp, arg2, ret);
5904
            }
5905
            free(dirp);
5906
        }
5907
#else
5908
        {
5909
            struct linux_dirent *dirp;
5910
            abi_long count = arg3;
5911

    
5912
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5913
                goto efault;
5914
            ret = get_errno(sys_getdents(arg1, dirp, count));
5915
            if (!is_error(ret)) {
5916
                struct linux_dirent *de;
5917
                int len = ret;
5918
                int reclen;
5919
                de = dirp;
5920
                while (len > 0) {
5921
                    reclen = de->d_reclen;
5922
                    if (reclen > len)
5923
                        break;
5924
                    de->d_reclen = tswap16(reclen);
5925
                    tswapls(&de->d_ino);
5926
                    tswapls(&de->d_off);
5927
                    de = (struct linux_dirent *)((char *)de + reclen);
5928
                    len -= reclen;
5929
                }
5930
            }
5931
            unlock_user(dirp, arg2, ret);
5932
        }
5933
#endif
5934
        break;
5935
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5936
    case TARGET_NR_getdents64:
5937
        {
5938
            struct linux_dirent64 *dirp;
5939
            abi_long count = arg3;
5940
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5941
                goto efault;
5942
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5943
            if (!is_error(ret)) {
5944
                struct linux_dirent64 *de;
5945
                int len = ret;
5946
                int reclen;
5947
                de = dirp;
5948
                while (len > 0) {
5949
                    reclen = de->d_reclen;
5950
                    if (reclen > len)
5951
                        break;
5952
                    de->d_reclen = tswap16(reclen);
5953
                    tswap64s((uint64_t *)&de->d_ino);
5954
                    tswap64s((uint64_t *)&de->d_off);
5955
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5956
                    len -= reclen;
5957
                }
5958
            }
5959
            unlock_user(dirp, arg2, ret);
5960
        }
5961
        break;
5962
#endif /* TARGET_NR_getdents64 */
5963
#ifdef TARGET_NR__newselect
5964
    case TARGET_NR__newselect:
5965
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5966
        break;
5967
#endif
5968
#ifdef TARGET_NR_poll
5969
    case TARGET_NR_poll:
5970
        {
5971
            struct target_pollfd *target_pfd;
5972
            unsigned int nfds = arg2;
5973
            int timeout = arg3;
5974
            struct pollfd *pfd;
5975
            unsigned int i;
5976

    
5977
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5978
            if (!target_pfd)
5979
                goto efault;
5980
            pfd = alloca(sizeof(struct pollfd) * nfds);
5981
            for(i = 0; i < nfds; i++) {
5982
                pfd[i].fd = tswap32(target_pfd[i].fd);
5983
                pfd[i].events = tswap16(target_pfd[i].events);
5984
            }
5985
            ret = get_errno(poll(pfd, nfds, timeout));
5986
            if (!is_error(ret)) {
5987
                for(i = 0; i < nfds; i++) {
5988
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5989
                }
5990
                ret += nfds * (sizeof(struct target_pollfd)
5991
                               - sizeof(struct pollfd));
5992
            }
5993
            unlock_user(target_pfd, arg1, ret);
5994
        }
5995
        break;
5996
#endif
5997
    case TARGET_NR_flock:
5998
        /* NOTE: the flock constant seems to be the same for every
5999
           Linux platform */
6000
        ret = get_errno(flock(arg1, arg2));
6001
        break;
6002
    case TARGET_NR_readv:
6003
        {
6004
            int count = arg3;
6005
            struct iovec *vec;
6006

    
6007
            vec = alloca(count * sizeof(struct iovec));
6008
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6009
                goto efault;
6010
            ret = get_errno(readv(arg1, vec, count));
6011
            unlock_iovec(vec, arg2, count, 1);
6012
        }
6013
        break;
6014
    case TARGET_NR_writev:
6015
        {
6016
            int count = arg3;
6017
            struct iovec *vec;
6018

    
6019
            vec = alloca(count * sizeof(struct iovec));
6020
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6021
                goto efault;
6022
            ret = get_errno(writev(arg1, vec, count));
6023
            unlock_iovec(vec, arg2, count, 0);
6024
        }
6025
        break;
6026
    case TARGET_NR_getsid:
6027
        ret = get_errno(getsid(arg1));
6028
        break;
6029
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6030
    case TARGET_NR_fdatasync:
6031
        ret = get_errno(fdatasync(arg1));
6032
        break;
6033
#endif
6034
    case TARGET_NR__sysctl:
6035
        /* We don't implement this, but ENOTDIR is always a safe
6036
           return value. */
6037
        ret = -TARGET_ENOTDIR;
6038
        break;
6039
    case TARGET_NR_sched_setparam:
6040
        {
6041
            struct sched_param *target_schp;
6042
            struct sched_param schp;
6043

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

    
6318
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6319
            ret = get_errno(getgroups(gidsetsize, grouplist));
6320
            if (gidsetsize == 0)
6321
                break;
6322
            if (!is_error(ret)) {
6323
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6324
                if (!target_grouplist)
6325
                    goto efault;
6326
                for(i = 0;i < ret; i++)
6327
                    target_grouplist[i] = tswap16(grouplist[i]);
6328
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6329
            }
6330
        }
6331
        break;
6332
    case TARGET_NR_setgroups:
6333
        {
6334
            int gidsetsize = arg1;
6335
            uint16_t *target_grouplist;
6336
            gid_t *grouplist;
6337
            int i;
6338

    
6339
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6340
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6341
            if (!target_grouplist) {
6342
                ret = -TARGET_EFAULT;
6343
                goto fail;
6344
            }
6345
            for(i = 0;i < gidsetsize; i++)
6346
                grouplist[i] = tswap16(target_grouplist[i]);
6347
            unlock_user(target_grouplist, arg2, 0);
6348
            ret = get_errno(setgroups(gidsetsize, grouplist));
6349
        }
6350
        break;
6351
    case TARGET_NR_fchown:
6352
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6353
        break;
6354
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6355
    case TARGET_NR_fchownat:
6356
        if (!(p = lock_user_string(arg2))) 
6357
            goto efault;
6358
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6359
        unlock_user(p, arg2, 0);
6360
        break;
6361
#endif
6362
#ifdef TARGET_NR_setresuid
6363
    case TARGET_NR_setresuid:
6364
        ret = get_errno(setresuid(low2highuid(arg1),
6365
                                  low2highuid(arg2),
6366
                                  low2highuid(arg3)));
6367
        break;
6368
#endif
6369
#ifdef TARGET_NR_getresuid
6370
    case TARGET_NR_getresuid:
6371
        {
6372
            uid_t ruid, euid, suid;
6373
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6374
            if (!is_error(ret)) {
6375
                if (put_user_u16(high2lowuid(ruid), arg1)
6376
                    || put_user_u16(high2lowuid(euid), arg2)
6377
                    || put_user_u16(high2lowuid(suid), arg3))
6378
                    goto efault;
6379
            }
6380
        }
6381
        break;
6382
#endif
6383
#ifdef TARGET_NR_getresgid
6384
    case TARGET_NR_setresgid:
6385
        ret = get_errno(setresgid(low2highgid(arg1),
6386
                                  low2highgid(arg2),
6387
                                  low2highgid(arg3)));
6388
        break;
6389
#endif
6390
#ifdef TARGET_NR_getresgid
6391
    case TARGET_NR_getresgid:
6392
        {
6393
            gid_t rgid, egid, sgid;
6394
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6395
            if (!is_error(ret)) {
6396
                if (put_user_u16(high2lowgid(rgid), arg1)
6397
                    || put_user_u16(high2lowgid(egid), arg2)
6398
                    || put_user_u16(high2lowgid(sgid), arg3))
6399
                    goto efault;
6400
            }
6401
        }
6402
        break;
6403
#endif
6404
    case TARGET_NR_chown:
6405
        if (!(p = lock_user_string(arg1)))
6406
            goto efault;
6407
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6408
        unlock_user(p, arg1, 0);
6409
        break;
6410
    case TARGET_NR_setuid:
6411
        ret = get_errno(setuid(low2highuid(arg1)));
6412
        break;
6413
    case TARGET_NR_setgid:
6414
        ret = get_errno(setgid(low2highgid(arg1)));
6415
        break;
6416
    case TARGET_NR_setfsuid:
6417
        ret = get_errno(setfsuid(arg1));
6418
        break;
6419
    case TARGET_NR_setfsgid:
6420
        ret = get_errno(setfsgid(arg1));
6421
        break;
6422
#endif /* USE_UID16 */
6423

    
6424
#ifdef TARGET_NR_lchown32
6425
    case TARGET_NR_lchown32:
6426
        if (!(p = lock_user_string(arg1)))
6427
            goto efault;
6428
        ret = get_errno(lchown(p, arg2, arg3));
6429
        unlock_user(p, arg1, 0);
6430
        break;
6431
#endif
6432
#ifdef TARGET_NR_getuid32
6433
    case TARGET_NR_getuid32:
6434
        ret = get_errno(getuid());
6435
        break;
6436
#endif
6437

    
6438
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6439
   /* Alpha specific */
6440
    case TARGET_NR_getxuid:
6441
         {
6442
            uid_t euid;
6443
            euid=geteuid();
6444
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6445
         }
6446
        ret = get_errno(getuid());
6447
        break;
6448
#endif
6449
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6450
   /* Alpha specific */
6451
    case TARGET_NR_getxgid:
6452
         {
6453
            uid_t egid;
6454
            egid=getegid();
6455
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6456
         }
6457
        ret = get_errno(getgid());
6458
        break;
6459
#endif
6460
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
6461
    /* Alpha specific */
6462
    case TARGET_NR_osf_getsysinfo:
6463
        ret = -TARGET_EOPNOTSUPP;
6464
        switch (arg1) {
6465
          case TARGET_GSI_IEEE_FP_CONTROL:
6466
            {
6467
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
6468

    
6469
                /* Copied from linux ieee_fpcr_to_swcr.  */
6470
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
6471
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
6472
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
6473
                                        | SWCR_TRAP_ENABLE_DZE
6474
                                        | SWCR_TRAP_ENABLE_OVF);
6475
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
6476
                                        | SWCR_TRAP_ENABLE_INE);
6477
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
6478
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
6479

    
6480
                if (put_user_u64 (swcr, arg2))
6481
                        goto efault;
6482
                ret = 0;
6483
            }
6484
            break;
6485

    
6486
          /* case GSI_IEEE_STATE_AT_SIGNAL:
6487
             -- Not implemented in linux kernel.
6488
             case GSI_UACPROC:
6489
             -- Retrieves current unaligned access state; not much used.
6490
             case GSI_PROC_TYPE:
6491
             -- Retrieves implver information; surely not used.
6492
             case GSI_GET_HWRPB:
6493
             -- Grabs a copy of the HWRPB; surely not used.
6494
          */
6495
        }
6496
        break;
6497
#endif
6498
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
6499
    /* Alpha specific */
6500
    case TARGET_NR_osf_setsysinfo:
6501
        ret = -TARGET_EOPNOTSUPP;
6502
        switch (arg1) {
6503
          case TARGET_SSI_IEEE_FP_CONTROL:
6504
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
6505
            {
6506
                uint64_t swcr, fpcr, orig_fpcr;
6507

    
6508
                if (get_user_u64 (swcr, arg2))
6509
                    goto efault;
6510
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6511
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6512

    
6513
                /* Copied from linux ieee_swcr_to_fpcr.  */
6514
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
6515
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
6516
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
6517
                                  | SWCR_TRAP_ENABLE_DZE
6518
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
6519
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
6520
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
6521
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
6522
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
6523

    
6524
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6525
                ret = 0;
6526

    
6527
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6528
                    /* Old exceptions are not signaled.  */
6529
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6530

    
6531
                    /* If any exceptions set by this call, and are unmasked,
6532
                       send a signal.  */
6533
                    /* ??? FIXME */
6534
                }
6535
            }
6536
            break;
6537

    
6538
          /* case SSI_NVPAIRS:
6539
             -- Used with SSIN_UACPROC to enable unaligned accesses.
6540
             case SSI_IEEE_STATE_AT_SIGNAL:
6541
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
6542
             -- Not implemented in linux kernel
6543
          */
6544
        }
6545
        break;
6546
#endif
6547
#ifdef TARGET_NR_osf_sigprocmask
6548
    /* Alpha specific.  */
6549
    case TARGET_NR_osf_sigprocmask:
6550
        {
6551
            abi_ulong mask;
6552
            int how = arg1;
6553
            sigset_t set, oldset;
6554

    
6555
            switch(arg1) {
6556
            case TARGET_SIG_BLOCK:
6557
                how = SIG_BLOCK;
6558
                break;
6559
            case TARGET_SIG_UNBLOCK:
6560
                how = SIG_UNBLOCK;
6561
                break;
6562
            case TARGET_SIG_SETMASK:
6563
                how = SIG_SETMASK;
6564
                break;
6565
            default:
6566
                ret = -TARGET_EINVAL;
6567
                goto fail;
6568
            }
6569
            mask = arg2;
6570
            target_to_host_old_sigset(&set, &mask);
6571
            sigprocmask(arg1, &set, &oldset);
6572
            host_to_target_old_sigset(&mask, &oldset);
6573
            ret = mask;
6574
        }
6575
        break;
6576
#endif
6577

    
6578
#ifdef TARGET_NR_getgid32
6579
    case TARGET_NR_getgid32:
6580
        ret = get_errno(getgid());
6581
        break;
6582
#endif
6583
#ifdef TARGET_NR_geteuid32
6584
    case TARGET_NR_geteuid32:
6585
        ret = get_errno(geteuid());
6586
        break;
6587
#endif
6588
#ifdef TARGET_NR_getegid32
6589
    case TARGET_NR_getegid32:
6590
        ret = get_errno(getegid());
6591
        break;
6592
#endif
6593
#ifdef TARGET_NR_setreuid32
6594
    case TARGET_NR_setreuid32:
6595
        ret = get_errno(setreuid(arg1, arg2));
6596
        break;
6597
#endif
6598
#ifdef TARGET_NR_setregid32
6599
    case TARGET_NR_setregid32:
6600
        ret = get_errno(setregid(arg1, arg2));
6601
        break;
6602
#endif
6603
#ifdef TARGET_NR_getgroups32
6604
    case TARGET_NR_getgroups32:
6605
        {
6606
            int gidsetsize = arg1;
6607
            uint32_t *target_grouplist;
6608
            gid_t *grouplist;
6609
            int i;
6610

    
6611
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6612
            ret = get_errno(getgroups(gidsetsize, grouplist));
6613
            if (gidsetsize == 0)
6614
                break;
6615
            if (!is_error(ret)) {
6616
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6617
                if (!target_grouplist) {
6618
                    ret = -TARGET_EFAULT;
6619
                    goto fail;
6620
                }
6621
                for(i = 0;i < ret; i++)
6622
                    target_grouplist[i] = tswap32(grouplist[i]);
6623
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6624
            }
6625
        }
6626
        break;
6627
#endif
6628
#ifdef TARGET_NR_setgroups32
6629
    case TARGET_NR_setgroups32:
6630
        {
6631
            int gidsetsize = arg1;
6632
            uint32_t *target_grouplist;
6633
            gid_t *grouplist;
6634
            int i;
6635

    
6636
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6637
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6638
            if (!target_grouplist) {
6639
                ret = -TARGET_EFAULT;
6640
                goto fail;
6641
            }
6642
            for(i = 0;i < gidsetsize; i++)
6643
                grouplist[i] = tswap32(target_grouplist[i]);
6644
            unlock_user(target_grouplist, arg2, 0);
6645
            ret = get_errno(setgroups(gidsetsize, grouplist));
6646
        }
6647
        break;
6648
#endif
6649
#ifdef TARGET_NR_fchown32
6650
    case TARGET_NR_fchown32:
6651
        ret = get_errno(fchown(arg1, arg2, arg3));
6652
        break;
6653
#endif
6654
#ifdef TARGET_NR_setresuid32
6655
    case TARGET_NR_setresuid32:
6656
        ret = get_errno(setresuid(arg1, arg2, arg3));
6657
        break;
6658
#endif
6659
#ifdef TARGET_NR_getresuid32
6660
    case TARGET_NR_getresuid32:
6661
        {
6662
            uid_t ruid, euid, suid;
6663
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6664
            if (!is_error(ret)) {
6665
                if (put_user_u32(ruid, arg1)
6666
                    || put_user_u32(euid, arg2)
6667
                    || put_user_u32(suid, arg3))
6668
                    goto efault;
6669
            }
6670
        }
6671
        break;
6672
#endif
6673
#ifdef TARGET_NR_setresgid32
6674
    case TARGET_NR_setresgid32:
6675
        ret = get_errno(setresgid(arg1, arg2, arg3));
6676
        break;
6677
#endif
6678
#ifdef TARGET_NR_getresgid32
6679
    case TARGET_NR_getresgid32:
6680
        {
6681
            gid_t rgid, egid, sgid;
6682
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6683
            if (!is_error(ret)) {
6684
                if (put_user_u32(rgid, arg1)
6685
                    || put_user_u32(egid, arg2)
6686
                    || put_user_u32(sgid, arg3))
6687
                    goto efault;
6688
            }
6689
        }
6690
        break;
6691
#endif
6692
#ifdef TARGET_NR_chown32
6693
    case TARGET_NR_chown32:
6694
        if (!(p = lock_user_string(arg1)))
6695
            goto efault;
6696
        ret = get_errno(chown(p, arg2, arg3));
6697
        unlock_user(p, arg1, 0);
6698
        break;
6699
#endif
6700
#ifdef TARGET_NR_setuid32
6701
    case TARGET_NR_setuid32:
6702
        ret = get_errno(setuid(arg1));
6703
        break;
6704
#endif
6705
#ifdef TARGET_NR_setgid32
6706
    case TARGET_NR_setgid32:
6707
        ret = get_errno(setgid(arg1));
6708
        break;
6709
#endif
6710
#ifdef TARGET_NR_setfsuid32
6711
    case TARGET_NR_setfsuid32:
6712
        ret = get_errno(setfsuid(arg1));
6713
        break;
6714
#endif
6715
#ifdef TARGET_NR_setfsgid32
6716
    case TARGET_NR_setfsgid32:
6717
        ret = get_errno(setfsgid(arg1));
6718
        break;
6719
#endif
6720

    
6721
    case TARGET_NR_pivot_root:
6722
        goto unimplemented;
6723
#ifdef TARGET_NR_mincore
6724
    case TARGET_NR_mincore:
6725
        {
6726
            void *a;
6727
            ret = -TARGET_EFAULT;
6728
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6729
                goto efault;
6730
            if (!(p = lock_user_string(arg3)))
6731
                goto mincore_fail;
6732
            ret = get_errno(mincore(a, arg2, p));
6733
            unlock_user(p, arg3, ret);
6734
            mincore_fail:
6735
            unlock_user(a, arg1, 0);
6736
        }
6737
        break;
6738
#endif
6739
#ifdef TARGET_NR_arm_fadvise64_64
6740
    case TARGET_NR_arm_fadvise64_64:
6741
        {
6742
                /*
6743
                 * arm_fadvise64_64 looks like fadvise64_64 but
6744
                 * with different argument order
6745
                 */
6746
                abi_long temp;
6747
                temp = arg3;
6748
                arg3 = arg4;
6749
                arg4 = temp;
6750
        }
6751
#endif
6752
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
6753
#ifdef TARGET_NR_fadvise64_64
6754
    case TARGET_NR_fadvise64_64:
6755
#endif
6756
#ifdef TARGET_NR_fadvise64
6757
    case TARGET_NR_fadvise64:
6758
#endif
6759
#ifdef TARGET_S390X
6760
        switch (arg4) {
6761
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
6762
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
6763
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
6764
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
6765
        default: break;
6766
        }
6767
#endif
6768
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
6769
        break;
6770
#endif
6771
#ifdef TARGET_NR_madvise
6772
    case TARGET_NR_madvise:
6773
        /* A straight passthrough may not be safe because qemu sometimes
6774
           turns private flie-backed mappings into anonymous mappings.
6775
           This will break MADV_DONTNEED.
6776
           This is a hint, so ignoring and returning success is ok.  */
6777
        ret = get_errno(0);
6778
        break;
6779
#endif
6780
#if TARGET_ABI_BITS == 32
6781
    case TARGET_NR_fcntl64:
6782
    {
6783
        int cmd;
6784
        struct flock64 fl;
6785
        struct target_flock64 *target_fl;
6786
#ifdef TARGET_ARM
6787
        struct target_eabi_flock64 *target_efl;
6788
#endif
6789

    
6790
        cmd = target_to_host_fcntl_cmd(arg2);
6791
        if (cmd == -TARGET_EINVAL)
6792
                return cmd;
6793

    
6794
        switch(arg2) {
6795
        case TARGET_F_GETLK64:
6796
#ifdef TARGET_ARM
6797
            if (((CPUARMState *)cpu_env)->eabi) {
6798
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6799
                    goto efault;
6800
                fl.l_type = tswap16(target_efl->l_type);
6801
                fl.l_whence = tswap16(target_efl->l_whence);
6802
                fl.l_start = tswap64(target_efl->l_start);
6803
                fl.l_len = tswap64(target_efl->l_len);
6804
                fl.l_pid = tswap32(target_efl->l_pid);
6805
                unlock_user_struct(target_efl, arg3, 0);
6806
            } else
6807
#endif
6808
            {
6809
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6810
                    goto efault;
6811
                fl.l_type = tswap16(target_fl->l_type);
6812
                fl.l_whence = tswap16(target_fl->l_whence);
6813
                fl.l_start = tswap64(target_fl->l_start);
6814
                fl.l_len = tswap64(target_fl->l_len);
6815
                fl.l_pid = tswap32(target_fl->l_pid);
6816
                unlock_user_struct(target_fl, arg3, 0);
6817
            }
6818
            ret = get_errno(fcntl(arg1, cmd, &fl));
6819
            if (ret == 0) {
6820
#ifdef TARGET_ARM
6821
                if (((CPUARMState *)cpu_env)->eabi) {
6822
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6823
                        goto efault;
6824
                    target_efl->l_type = tswap16(fl.l_type);
6825
                    target_efl->l_whence = tswap16(fl.l_whence);
6826
                    target_efl->l_start = tswap64(fl.l_start);
6827
                    target_efl->l_len = tswap64(fl.l_len);
6828
                    target_efl->l_pid = tswap32(fl.l_pid);
6829
                    unlock_user_struct(target_efl, arg3, 1);
6830
                } else
6831
#endif
6832
                {
6833
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6834
                        goto efault;
6835
                    target_fl->l_type = tswap16(fl.l_type);
6836
                    target_fl->l_whence = tswap16(fl.l_whence);
6837
                    target_fl->l_start = tswap64(fl.l_start);
6838
                    target_fl->l_len = tswap64(fl.l_len);
6839
                    target_fl->l_pid = tswap32(fl.l_pid);
6840
                    unlock_user_struct(target_fl, arg3, 1);
6841
                }
6842
            }
6843
            break;
6844

    
6845
        case TARGET_F_SETLK64:
6846
        case TARGET_F_SETLKW64:
6847
#ifdef TARGET_ARM
6848
            if (((CPUARMState *)cpu_env)->eabi) {
6849
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6850
                    goto efault;
6851
                fl.l_type = tswap16(target_efl->l_type);
6852
                fl.l_whence = tswap16(target_efl->l_whence);
6853
                fl.l_start = tswap64(target_efl->l_start);
6854
                fl.l_len = tswap64(target_efl->l_len);
6855
                fl.l_pid = tswap32(target_efl->l_pid);
6856
                unlock_user_struct(target_efl, arg3, 0);
6857
            } else
6858
#endif
6859
            {
6860
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6861
                    goto efault;
6862
                fl.l_type = tswap16(target_fl->l_type);
6863
                fl.l_whence = tswap16(target_fl->l_whence);
6864
                fl.l_start = tswap64(target_fl->l_start);
6865
                fl.l_len = tswap64(target_fl->l_len);
6866
                fl.l_pid = tswap32(target_fl->l_pid);
6867
                unlock_user_struct(target_fl, arg3, 0);
6868
            }
6869
            ret = get_errno(fcntl(arg1, cmd, &fl));
6870
            break;
6871
        default:
6872
            ret = do_fcntl(arg1, arg2, arg3);
6873
            break;
6874
        }
6875
        break;
6876
    }
6877
#endif
6878
#ifdef TARGET_NR_cacheflush
6879
    case TARGET_NR_cacheflush:
6880
        /* self-modifying code is handled automatically, so nothing needed */
6881
        ret = 0;
6882
        break;
6883
#endif
6884
#ifdef TARGET_NR_security
6885
    case TARGET_NR_security:
6886
        goto unimplemented;
6887
#endif
6888
#ifdef TARGET_NR_getpagesize
6889
    case TARGET_NR_getpagesize:
6890
        ret = TARGET_PAGE_SIZE;
6891
        break;
6892
#endif
6893
    case TARGET_NR_gettid:
6894
        ret = get_errno(gettid());
6895
        break;
6896
#ifdef TARGET_NR_readahead
6897
    case TARGET_NR_readahead:
6898
#if TARGET_ABI_BITS == 32
6899
#ifdef TARGET_ARM
6900
        if (((CPUARMState *)cpu_env)->eabi)
6901
        {
6902
            arg2 = arg3;
6903
            arg3 = arg4;
6904
            arg4 = arg5;
6905
        }
6906
#endif
6907
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6908
#else
6909
        ret = get_errno(readahead(arg1, arg2, arg3));
6910
#endif
6911
        break;
6912
#endif
6913
#ifdef TARGET_NR_setxattr
6914
    case TARGET_NR_setxattr:
6915
    case TARGET_NR_lsetxattr:
6916
    case TARGET_NR_fsetxattr:
6917
    case TARGET_NR_getxattr:
6918
    case TARGET_NR_lgetxattr:
6919
    case TARGET_NR_fgetxattr:
6920
    case TARGET_NR_listxattr:
6921
    case TARGET_NR_llistxattr:
6922
    case TARGET_NR_flistxattr:
6923
    case TARGET_NR_removexattr:
6924
    case TARGET_NR_lremovexattr:
6925
    case TARGET_NR_fremovexattr:
6926
        ret = -TARGET_EOPNOTSUPP;
6927
        break;
6928
#endif
6929
#ifdef TARGET_NR_set_thread_area
6930
    case TARGET_NR_set_thread_area:
6931
#if defined(TARGET_MIPS)
6932
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6933
      ret = 0;
6934
      break;
6935
#elif defined(TARGET_CRIS)
6936
      if (arg1 & 0xff)
6937
          ret = -TARGET_EINVAL;
6938
      else {
6939
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6940
          ret = 0;
6941
      }
6942
      break;
6943
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6944
      ret = do_set_thread_area(cpu_env, arg1);
6945
      break;
6946
#else
6947
      goto unimplemented_nowarn;
6948
#endif
6949
#endif
6950
#ifdef TARGET_NR_get_thread_area
6951
    case TARGET_NR_get_thread_area:
6952
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6953
        ret = do_get_thread_area(cpu_env, arg1);
6954
#else
6955
        goto unimplemented_nowarn;
6956
#endif
6957
#endif
6958
#ifdef TARGET_NR_getdomainname
6959
    case TARGET_NR_getdomainname:
6960
        goto unimplemented_nowarn;
6961
#endif
6962

    
6963
#ifdef TARGET_NR_clock_gettime
6964
    case TARGET_NR_clock_gettime:
6965
    {
6966
        struct timespec ts;
6967
        ret = get_errno(clock_gettime(arg1, &ts));
6968
        if (!is_error(ret)) {
6969
            host_to_target_timespec(arg2, &ts);
6970
        }
6971
        break;
6972
    }
6973
#endif
6974
#ifdef TARGET_NR_clock_getres
6975
    case TARGET_NR_clock_getres:
6976
    {
6977
        struct timespec ts;
6978
        ret = get_errno(clock_getres(arg1, &ts));
6979
        if (!is_error(ret)) {
6980
            host_to_target_timespec(arg2, &ts);
6981
        }
6982
        break;
6983
    }
6984
#endif
6985
#ifdef TARGET_NR_clock_nanosleep
6986
    case TARGET_NR_clock_nanosleep:
6987
    {
6988
        struct timespec ts;
6989
        target_to_host_timespec(&ts, arg3);
6990
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6991
        if (arg4)
6992
            host_to_target_timespec(arg4, &ts);
6993
        break;
6994
    }
6995
#endif
6996

    
6997
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6998
    case TARGET_NR_set_tid_address:
6999
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7000
        break;
7001
#endif
7002

    
7003
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7004
    case TARGET_NR_tkill:
7005
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7006
        break;
7007
#endif
7008

    
7009
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7010
    case TARGET_NR_tgkill:
7011
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7012
                        target_to_host_signal(arg3)));
7013
        break;
7014
#endif
7015

    
7016
#ifdef TARGET_NR_set_robust_list
7017
    case TARGET_NR_set_robust_list:
7018
        goto unimplemented_nowarn;
7019
#endif
7020

    
7021
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7022
    case TARGET_NR_utimensat:
7023
        {
7024
            struct timespec *tsp, ts[2];
7025
            if (!arg3) {
7026
                tsp = NULL;
7027
            } else {
7028
                target_to_host_timespec(ts, arg3);
7029
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7030
                tsp = ts;
7031
            }
7032
            if (!arg2)
7033
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7034
            else {
7035
                if (!(p = lock_user_string(arg2))) {
7036
                    ret = -TARGET_EFAULT;
7037
                    goto fail;
7038
                }
7039
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7040
                unlock_user(p, arg2, 0);
7041
            }
7042
        }
7043
        break;
7044
#endif
7045
#if defined(CONFIG_USE_NPTL)
7046
    case TARGET_NR_futex:
7047
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7048
        break;
7049
#endif
7050
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7051
    case TARGET_NR_inotify_init:
7052
        ret = get_errno(sys_inotify_init());
7053
        break;
7054
#endif
7055
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7056
    case TARGET_NR_inotify_add_watch:
7057
        p = lock_user_string(arg2);
7058
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7059
        unlock_user(p, arg2, 0);
7060
        break;
7061
#endif
7062
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7063
    case TARGET_NR_inotify_rm_watch:
7064
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7065
        break;
7066
#endif
7067

    
7068
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7069
    case TARGET_NR_mq_open:
7070
        {
7071
            struct mq_attr posix_mq_attr;
7072

    
7073
            p = lock_user_string(arg1 - 1);
7074
            if (arg4 != 0)
7075
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7076
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7077
            unlock_user (p, arg1, 0);
7078
        }
7079
        break;
7080

    
7081
    case TARGET_NR_mq_unlink:
7082
        p = lock_user_string(arg1 - 1);
7083
        ret = get_errno(mq_unlink(p));
7084
        unlock_user (p, arg1, 0);
7085
        break;
7086

    
7087
    case TARGET_NR_mq_timedsend:
7088
        {
7089
            struct timespec ts;
7090

    
7091
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7092
            if (arg5 != 0) {
7093
                target_to_host_timespec(&ts, arg5);
7094
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7095
                host_to_target_timespec(arg5, &ts);
7096
            }
7097
            else
7098
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7099
            unlock_user (p, arg2, arg3);
7100
        }
7101
        break;
7102

    
7103
    case TARGET_NR_mq_timedreceive:
7104
        {
7105
            struct timespec ts;
7106
            unsigned int prio;
7107

    
7108
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7109
            if (arg5 != 0) {
7110
                target_to_host_timespec(&ts, arg5);
7111
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7112
                host_to_target_timespec(arg5, &ts);
7113
            }
7114
            else
7115
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7116
            unlock_user (p, arg2, arg3);
7117
            if (arg4 != 0)
7118
                put_user_u32(prio, arg4);
7119
        }
7120
        break;
7121

    
7122
    /* Not implemented for now... */
7123
/*     case TARGET_NR_mq_notify: */
7124
/*         break; */
7125

    
7126
    case TARGET_NR_mq_getsetattr:
7127
        {
7128
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7129
            ret = 0;
7130
            if (arg3 != 0) {
7131
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7132
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7133
            }
7134
            if (arg2 != 0) {
7135
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7136
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7137
            }
7138

    
7139
        }
7140
        break;
7141
#endif
7142

    
7143
#ifdef CONFIG_SPLICE
7144
#ifdef TARGET_NR_tee
7145
    case TARGET_NR_tee:
7146
        {
7147
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7148
        }
7149
        break;
7150
#endif
7151
#ifdef TARGET_NR_splice
7152
    case TARGET_NR_splice:
7153
        {
7154
            loff_t loff_in, loff_out;
7155
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7156
            if(arg2) {
7157
                get_user_u64(loff_in, arg2);
7158
                ploff_in = &loff_in;
7159
            }
7160
            if(arg4) {
7161
                get_user_u64(loff_out, arg2);
7162
                ploff_out = &loff_out;
7163
            }
7164
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7165
        }
7166
        break;
7167
#endif
7168
#ifdef TARGET_NR_vmsplice
7169
        case TARGET_NR_vmsplice:
7170
        {
7171
            int count = arg3;
7172
            struct iovec *vec;
7173

    
7174
            vec = alloca(count * sizeof(struct iovec));
7175
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7176
                goto efault;
7177
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7178
            unlock_iovec(vec, arg2, count, 0);
7179
        }
7180
        break;
7181
#endif
7182
#endif /* CONFIG_SPLICE */
7183
#ifdef CONFIG_EVENTFD
7184
#if defined(TARGET_NR_eventfd)
7185
    case TARGET_NR_eventfd:
7186
        ret = get_errno(eventfd(arg1, 0));
7187
        break;
7188
#endif
7189
#if defined(TARGET_NR_eventfd2)
7190
    case TARGET_NR_eventfd2:
7191
        ret = get_errno(eventfd(arg1, arg2));
7192
        break;
7193
#endif
7194
#endif /* CONFIG_EVENTFD  */
7195
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7196
    case TARGET_NR_fallocate:
7197
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7198
        break;
7199
#endif
7200
    default:
7201
    unimplemented:
7202
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7203
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7204
    unimplemented_nowarn:
7205
#endif
7206
        ret = -TARGET_ENOSYS;
7207
        break;
7208
    }
7209
fail:
7210
#ifdef DEBUG
7211
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7212
#endif
7213
    if(do_strace)
7214
        print_syscall_ret(num, ret);
7215
    return ret;
7216
efault:
7217
    ret = -TARGET_EFAULT;
7218
    goto fail;
7219
}