Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ c05c7a73

History | View | Annotate | Download (222.2 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
#ifdef CONFIG_INOTIFY1
510
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
511
static int sys_inotify_init1(int flags)
512
{
513
  return (inotify_init1(flags));
514
}
515
#endif
516
#endif
517
#else
518
/* Userspace can usually survive runtime without inotify */
519
#undef TARGET_NR_inotify_init
520
#undef TARGET_NR_inotify_init1
521
#undef TARGET_NR_inotify_add_watch
522
#undef TARGET_NR_inotify_rm_watch
523
#endif /* CONFIG_INOTIFY  */
524

    
525

    
526
extern int personality(int);
527
extern int flock(int, int);
528
extern int setfsuid(int);
529
extern int setfsgid(int);
530
extern int setgroups(int, gid_t *);
531

    
532
#define ERRNO_TABLE_SIZE 1200
533

    
534
/* target_to_host_errno_table[] is initialized from
535
 * host_to_target_errno_table[] in syscall_init(). */
536
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
537
};
538

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

    
651
static inline int host_to_target_errno(int err)
652
{
653
    if(host_to_target_errno_table[err])
654
        return host_to_target_errno_table[err];
655
    return err;
656
}
657

    
658
static inline int target_to_host_errno(int err)
659
{
660
    if (target_to_host_errno_table[err])
661
        return target_to_host_errno_table[err];
662
    return err;
663
}
664

    
665
static inline abi_long get_errno(abi_long ret)
666
{
667
    if (ret == -1)
668
        return -host_to_target_errno(errno);
669
    else
670
        return ret;
671
}
672

    
673
static inline int is_error(abi_long ret)
674
{
675
    return (abi_ulong)ret >= (abi_ulong)(-4096);
676
}
677

    
678
char *target_strerror(int err)
679
{
680
    return strerror(target_to_host_errno(err));
681
}
682

    
683
static abi_ulong target_brk;
684
static abi_ulong target_original_brk;
685

    
686
void target_set_brk(abi_ulong new_brk)
687
{
688
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
689
}
690

    
691
/* do_brk() must return target values and target errnos. */
692
abi_long do_brk(abi_ulong new_brk)
693
{
694
    abi_ulong brk_page;
695
    abi_long mapped_addr;
696
    int        new_alloc_size;
697

    
698
    if (!new_brk)
699
        return target_brk;
700
    if (new_brk < target_original_brk)
701
        return target_brk;
702

    
703
    brk_page = HOST_PAGE_ALIGN(target_brk);
704

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

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

    
717
    if (!is_error(mapped_addr))
718
        target_brk = new_brk;
719
    
720
    return target_brk;
721
}
722

    
723
static inline abi_long copy_from_user_fdset(fd_set *fds,
724
                                            abi_ulong target_fds_addr,
725
                                            int n)
726
{
727
    int i, nw, j, k;
728
    abi_ulong b, *target_fds;
729

    
730
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
731
    if (!(target_fds = lock_user(VERIFY_READ,
732
                                 target_fds_addr,
733
                                 sizeof(abi_ulong) * nw,
734
                                 1)))
735
        return -TARGET_EFAULT;
736

    
737
    FD_ZERO(fds);
738
    k = 0;
739
    for (i = 0; i < nw; i++) {
740
        /* grab the abi_ulong */
741
        __get_user(b, &target_fds[i]);
742
        for (j = 0; j < TARGET_ABI_BITS; j++) {
743
            /* check the bit inside the abi_ulong */
744
            if ((b >> j) & 1)
745
                FD_SET(k, fds);
746
            k++;
747
        }
748
    }
749

    
750
    unlock_user(target_fds, target_fds_addr, 0);
751

    
752
    return 0;
753
}
754

    
755
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
756
                                          const fd_set *fds,
757
                                          int n)
758
{
759
    int i, nw, j, k;
760
    abi_long v;
761
    abi_ulong *target_fds;
762

    
763
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
764
    if (!(target_fds = lock_user(VERIFY_WRITE,
765
                                 target_fds_addr,
766
                                 sizeof(abi_ulong) * nw,
767
                                 0)))
768
        return -TARGET_EFAULT;
769

    
770
    k = 0;
771
    for (i = 0; i < nw; i++) {
772
        v = 0;
773
        for (j = 0; j < TARGET_ABI_BITS; j++) {
774
            v |= ((FD_ISSET(k, fds) != 0) << j);
775
            k++;
776
        }
777
        __put_user(v, &target_fds[i]);
778
    }
779

    
780
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
781

    
782
    return 0;
783
}
784

    
785
#if defined(__alpha__)
786
#define HOST_HZ 1024
787
#else
788
#define HOST_HZ 100
789
#endif
790

    
791
static inline abi_long host_to_target_clock_t(long ticks)
792
{
793
#if HOST_HZ == TARGET_HZ
794
    return ticks;
795
#else
796
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
797
#endif
798
}
799

    
800
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
801
                                             const struct rusage *rusage)
802
{
803
    struct target_rusage *target_rusage;
804

    
805
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
806
        return -TARGET_EFAULT;
807
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
808
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
809
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
810
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
811
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
812
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
813
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
814
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
815
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
816
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
817
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
818
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
819
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
820
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
821
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
822
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
823
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
824
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
825
    unlock_user_struct(target_rusage, target_addr, 1);
826

    
827
    return 0;
828
}
829

    
830
static inline abi_long copy_from_user_timeval(struct timeval *tv,
831
                                              abi_ulong target_tv_addr)
832
{
833
    struct target_timeval *target_tv;
834

    
835
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
836
        return -TARGET_EFAULT;
837

    
838
    __get_user(tv->tv_sec, &target_tv->tv_sec);
839
    __get_user(tv->tv_usec, &target_tv->tv_usec);
840

    
841
    unlock_user_struct(target_tv, target_tv_addr, 0);
842

    
843
    return 0;
844
}
845

    
846
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
847
                                            const struct timeval *tv)
848
{
849
    struct target_timeval *target_tv;
850

    
851
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
852
        return -TARGET_EFAULT;
853

    
854
    __put_user(tv->tv_sec, &target_tv->tv_sec);
855
    __put_user(tv->tv_usec, &target_tv->tv_usec);
856

    
857
    unlock_user_struct(target_tv, target_tv_addr, 1);
858

    
859
    return 0;
860
}
861

    
862
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
863
#include <mqueue.h>
864

    
865
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
866
                                              abi_ulong target_mq_attr_addr)
867
{
868
    struct target_mq_attr *target_mq_attr;
869

    
870
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
871
                          target_mq_attr_addr, 1))
872
        return -TARGET_EFAULT;
873

    
874
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
875
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
876
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
877
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
878

    
879
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
880

    
881
    return 0;
882
}
883

    
884
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
885
                                            const struct mq_attr *attr)
886
{
887
    struct target_mq_attr *target_mq_attr;
888

    
889
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
890
                          target_mq_attr_addr, 0))
891
        return -TARGET_EFAULT;
892

    
893
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
894
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
895
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
896
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
897

    
898
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
899

    
900
    return 0;
901
}
902
#endif
903

    
904
/* do_select() must return target values and target errnos. */
905
static abi_long do_select(int n,
906
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
907
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
908
{
909
    fd_set rfds, wfds, efds;
910
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
911
    struct timeval tv, *tv_ptr;
912
    abi_long ret;
913

    
914
    if (rfd_addr) {
915
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
916
            return -TARGET_EFAULT;
917
        rfds_ptr = &rfds;
918
    } else {
919
        rfds_ptr = NULL;
920
    }
921
    if (wfd_addr) {
922
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
923
            return -TARGET_EFAULT;
924
        wfds_ptr = &wfds;
925
    } else {
926
        wfds_ptr = NULL;
927
    }
928
    if (efd_addr) {
929
        if (copy_from_user_fdset(&efds, efd_addr, n))
930
            return -TARGET_EFAULT;
931
        efds_ptr = &efds;
932
    } else {
933
        efds_ptr = NULL;
934
    }
935

    
936
    if (target_tv_addr) {
937
        if (copy_from_user_timeval(&tv, target_tv_addr))
938
            return -TARGET_EFAULT;
939
        tv_ptr = &tv;
940
    } else {
941
        tv_ptr = NULL;
942
    }
943

    
944
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
945

    
946
    if (!is_error(ret)) {
947
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
948
            return -TARGET_EFAULT;
949
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
950
            return -TARGET_EFAULT;
951
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
952
            return -TARGET_EFAULT;
953

    
954
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
955
            return -TARGET_EFAULT;
956
    }
957

    
958
    return ret;
959
}
960

    
961
static abi_long do_pipe2(int host_pipe[], int flags)
962
{
963
#ifdef CONFIG_PIPE2
964
    return pipe2(host_pipe, flags);
965
#else
966
    return -ENOSYS;
967
#endif
968
}
969

    
970
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
971
{
972
    int host_pipe[2];
973
    abi_long ret;
974
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
975

    
976
    if (is_error(ret))
977
        return get_errno(ret);
978
#if defined(TARGET_MIPS)
979
    ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
980
    ret = host_pipe[0];
981
#else
982
#if defined(TARGET_SH4)
983
    if (!flags) {
984
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
985
        ret = host_pipe[0];
986
    } else
987
#endif
988
    if (put_user_s32(host_pipe[0], pipedes)
989
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
990
        return -TARGET_EFAULT;
991
#endif
992
    return get_errno(ret);
993
}
994

    
995
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
996
                                              abi_ulong target_addr,
997
                                              socklen_t len)
998
{
999
    struct target_ip_mreqn *target_smreqn;
1000

    
1001
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1002
    if (!target_smreqn)
1003
        return -TARGET_EFAULT;
1004
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1005
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1006
    if (len == sizeof(struct target_ip_mreqn))
1007
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1008
    unlock_user(target_smreqn, target_addr, 0);
1009

    
1010
    return 0;
1011
}
1012

    
1013
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1014
                                               abi_ulong target_addr,
1015
                                               socklen_t len)
1016
{
1017
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1018
    sa_family_t sa_family;
1019
    struct target_sockaddr *target_saddr;
1020

    
1021
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1022
    if (!target_saddr)
1023
        return -TARGET_EFAULT;
1024

    
1025
    sa_family = tswap16(target_saddr->sa_family);
1026

    
1027
    /* Oops. The caller might send a incomplete sun_path; sun_path
1028
     * must be terminated by \0 (see the manual page), but
1029
     * unfortunately it is quite common to specify sockaddr_un
1030
     * length as "strlen(x->sun_path)" while it should be
1031
     * "strlen(...) + 1". We'll fix that here if needed.
1032
     * Linux kernel has a similar feature.
1033
     */
1034

    
1035
    if (sa_family == AF_UNIX) {
1036
        if (len < unix_maxlen && len > 0) {
1037
            char *cp = (char*)target_saddr;
1038

    
1039
            if ( cp[len-1] && !cp[len] )
1040
                len++;
1041
        }
1042
        if (len > unix_maxlen)
1043
            len = unix_maxlen;
1044
    }
1045

    
1046
    memcpy(addr, target_saddr, len);
1047
    addr->sa_family = sa_family;
1048
    unlock_user(target_saddr, target_addr, 0);
1049

    
1050
    return 0;
1051
}
1052

    
1053
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1054
                                               struct sockaddr *addr,
1055
                                               socklen_t len)
1056
{
1057
    struct target_sockaddr *target_saddr;
1058

    
1059
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1060
    if (!target_saddr)
1061
        return -TARGET_EFAULT;
1062
    memcpy(target_saddr, addr, len);
1063
    target_saddr->sa_family = tswap16(addr->sa_family);
1064
    unlock_user(target_saddr, target_addr, len);
1065

    
1066
    return 0;
1067
}
1068

    
1069
/* ??? Should this also swap msgh->name?  */
1070
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1071
                                           struct target_msghdr *target_msgh)
1072
{
1073
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1074
    abi_long msg_controllen;
1075
    abi_ulong target_cmsg_addr;
1076
    struct target_cmsghdr *target_cmsg;
1077
    socklen_t space = 0;
1078
    
1079
    msg_controllen = tswapl(target_msgh->msg_controllen);
1080
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1081
        goto the_end;
1082
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1083
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1084
    if (!target_cmsg)
1085
        return -TARGET_EFAULT;
1086

    
1087
    while (cmsg && target_cmsg) {
1088
        void *data = CMSG_DATA(cmsg);
1089
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1090

    
1091
        int len = tswapl(target_cmsg->cmsg_len)
1092
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1093

    
1094
        space += CMSG_SPACE(len);
1095
        if (space > msgh->msg_controllen) {
1096
            space -= CMSG_SPACE(len);
1097
            gemu_log("Host cmsg overflow\n");
1098
            break;
1099
        }
1100

    
1101
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1102
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1103
        cmsg->cmsg_len = CMSG_LEN(len);
1104

    
1105
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1106
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1107
            memcpy(data, target_data, len);
1108
        } else {
1109
            int *fd = (int *)data;
1110
            int *target_fd = (int *)target_data;
1111
            int i, numfds = len / sizeof(int);
1112

    
1113
            for (i = 0; i < numfds; i++)
1114
                fd[i] = tswap32(target_fd[i]);
1115
        }
1116

    
1117
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1118
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1119
    }
1120
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1121
 the_end:
1122
    msgh->msg_controllen = space;
1123
    return 0;
1124
}
1125

    
1126
/* ??? Should this also swap msgh->name?  */
1127
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1128
                                           struct msghdr *msgh)
1129
{
1130
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1131
    abi_long msg_controllen;
1132
    abi_ulong target_cmsg_addr;
1133
    struct target_cmsghdr *target_cmsg;
1134
    socklen_t space = 0;
1135

    
1136
    msg_controllen = tswapl(target_msgh->msg_controllen);
1137
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1138
        goto the_end;
1139
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1140
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1141
    if (!target_cmsg)
1142
        return -TARGET_EFAULT;
1143

    
1144
    while (cmsg && target_cmsg) {
1145
        void *data = CMSG_DATA(cmsg);
1146
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1147

    
1148
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1149

    
1150
        space += TARGET_CMSG_SPACE(len);
1151
        if (space > msg_controllen) {
1152
            space -= TARGET_CMSG_SPACE(len);
1153
            gemu_log("Target cmsg overflow\n");
1154
            break;
1155
        }
1156

    
1157
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1158
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1159
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1160

    
1161
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1162
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1163
            memcpy(target_data, data, len);
1164
        } else {
1165
            int *fd = (int *)data;
1166
            int *target_fd = (int *)target_data;
1167
            int i, numfds = len / sizeof(int);
1168

    
1169
            for (i = 0; i < numfds; i++)
1170
                target_fd[i] = tswap32(fd[i]);
1171
        }
1172

    
1173
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1174
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1175
    }
1176
    unlock_user(target_cmsg, target_cmsg_addr, space);
1177
 the_end:
1178
    target_msgh->msg_controllen = tswapl(space);
1179
    return 0;
1180
}
1181

    
1182
/* do_setsockopt() Must return target values and target errnos. */
1183
static abi_long do_setsockopt(int sockfd, int level, int optname,
1184
                              abi_ulong optval_addr, socklen_t optlen)
1185
{
1186
    abi_long ret;
1187
    int val;
1188
    struct ip_mreqn *ip_mreq;
1189
    struct ip_mreq_source *ip_mreq_source;
1190

    
1191
    switch(level) {
1192
    case SOL_TCP:
1193
        /* TCP options all take an 'int' value.  */
1194
        if (optlen < sizeof(uint32_t))
1195
            return -TARGET_EINVAL;
1196

    
1197
        if (get_user_u32(val, optval_addr))
1198
            return -TARGET_EFAULT;
1199
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1200
        break;
1201
    case SOL_IP:
1202
        switch(optname) {
1203
        case IP_TOS:
1204
        case IP_TTL:
1205
        case IP_HDRINCL:
1206
        case IP_ROUTER_ALERT:
1207
        case IP_RECVOPTS:
1208
        case IP_RETOPTS:
1209
        case IP_PKTINFO:
1210
        case IP_MTU_DISCOVER:
1211
        case IP_RECVERR:
1212
        case IP_RECVTOS:
1213
#ifdef IP_FREEBIND
1214
        case IP_FREEBIND:
1215
#endif
1216
        case IP_MULTICAST_TTL:
1217
        case IP_MULTICAST_LOOP:
1218
            val = 0;
1219
            if (optlen >= sizeof(uint32_t)) {
1220
                if (get_user_u32(val, optval_addr))
1221
                    return -TARGET_EFAULT;
1222
            } else if (optlen >= 1) {
1223
                if (get_user_u8(val, optval_addr))
1224
                    return -TARGET_EFAULT;
1225
            }
1226
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1227
            break;
1228
        case IP_ADD_MEMBERSHIP:
1229
        case IP_DROP_MEMBERSHIP:
1230
            if (optlen < sizeof (struct target_ip_mreq) ||
1231
                optlen > sizeof (struct target_ip_mreqn))
1232
                return -TARGET_EINVAL;
1233

    
1234
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1235
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1236
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1237
            break;
1238

    
1239
        case IP_BLOCK_SOURCE:
1240
        case IP_UNBLOCK_SOURCE:
1241
        case IP_ADD_SOURCE_MEMBERSHIP:
1242
        case IP_DROP_SOURCE_MEMBERSHIP:
1243
            if (optlen != sizeof (struct target_ip_mreq_source))
1244
                return -TARGET_EINVAL;
1245

    
1246
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1247
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1248
            unlock_user (ip_mreq_source, optval_addr, 0);
1249
            break;
1250

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

    
1321
        if (get_user_u32(val, optval_addr))
1322
            return -TARGET_EFAULT;
1323
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1324
        break;
1325
    default:
1326
    unimplemented:
1327
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1328
        ret = -TARGET_ENOPROTOOPT;
1329
    }
1330
    return ret;
1331
}
1332

    
1333
/* do_getsockopt() Must return target values and target errnos. */
1334
static abi_long do_getsockopt(int sockfd, int level, int optname,
1335
                              abi_ulong optval_addr, abi_ulong optlen)
1336
{
1337
    abi_long ret;
1338
    int len, val;
1339
    socklen_t lv;
1340

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

    
1432
/* FIXME
1433
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1434
 * other lock functions have a return code of 0 for failure.
1435
 */
1436
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1437
                           int count, int copy)
1438
{
1439
    struct target_iovec *target_vec;
1440
    abi_ulong base;
1441
    int i;
1442

    
1443
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1444
    if (!target_vec)
1445
        return -TARGET_EFAULT;
1446
    for(i = 0;i < count; i++) {
1447
        base = tswapl(target_vec[i].iov_base);
1448
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1449
        if (vec[i].iov_len != 0) {
1450
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1451
            /* Don't check lock_user return value. We must call writev even
1452
               if a element has invalid base address. */
1453
        } else {
1454
            /* zero length pointer is ignored */
1455
            vec[i].iov_base = NULL;
1456
        }
1457
    }
1458
    unlock_user (target_vec, target_addr, 0);
1459
    return 0;
1460
}
1461

    
1462
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1463
                             int count, int copy)
1464
{
1465
    struct target_iovec *target_vec;
1466
    abi_ulong base;
1467
    int i;
1468

    
1469
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1470
    if (!target_vec)
1471
        return -TARGET_EFAULT;
1472
    for(i = 0;i < count; i++) {
1473
        if (target_vec[i].iov_base) {
1474
            base = tswapl(target_vec[i].iov_base);
1475
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1476
        }
1477
    }
1478
    unlock_user (target_vec, target_addr, 0);
1479

    
1480
    return 0;
1481
}
1482

    
1483
/* do_socket() Must return target values and target errnos. */
1484
static abi_long do_socket(int domain, int type, int protocol)
1485
{
1486
#if defined(TARGET_MIPS)
1487
    switch(type) {
1488
    case TARGET_SOCK_DGRAM:
1489
        type = SOCK_DGRAM;
1490
        break;
1491
    case TARGET_SOCK_STREAM:
1492
        type = SOCK_STREAM;
1493
        break;
1494
    case TARGET_SOCK_RAW:
1495
        type = SOCK_RAW;
1496
        break;
1497
    case TARGET_SOCK_RDM:
1498
        type = SOCK_RDM;
1499
        break;
1500
    case TARGET_SOCK_SEQPACKET:
1501
        type = SOCK_SEQPACKET;
1502
        break;
1503
    case TARGET_SOCK_PACKET:
1504
        type = SOCK_PACKET;
1505
        break;
1506
    }
1507
#endif
1508
    if (domain == PF_NETLINK)
1509
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1510
    return get_errno(socket(domain, type, protocol));
1511
}
1512

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

    
1520
    if (addrlen < 0)
1521
        return -TARGET_EINVAL;
1522

    
1523
    addr = alloca(addrlen+1);
1524

    
1525
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1526
    if (ret)
1527
        return ret;
1528

    
1529
    return get_errno(bind(sockfd, addr, addrlen));
1530
}
1531

    
1532
/* do_connect() Must return target values and target errnos. */
1533
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1534
                           socklen_t addrlen)
1535
{
1536
    void *addr;
1537
    abi_long ret;
1538

    
1539
    if (addrlen < 0)
1540
        return -TARGET_EINVAL;
1541

    
1542
    addr = alloca(addrlen);
1543

    
1544
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1545
    if (ret)
1546
        return ret;
1547

    
1548
    return get_errno(connect(sockfd, addr, addrlen));
1549
}
1550

    
1551
/* do_sendrecvmsg() Must return target values and target errnos. */
1552
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1553
                               int flags, int send)
1554
{
1555
    abi_long ret, len;
1556
    struct target_msghdr *msgp;
1557
    struct msghdr msg;
1558
    int count;
1559
    struct iovec *vec;
1560
    abi_ulong target_vec;
1561

    
1562
    /* FIXME */
1563
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1564
                          msgp,
1565
                          target_msg,
1566
                          send ? 1 : 0))
1567
        return -TARGET_EFAULT;
1568
    if (msgp->msg_name) {
1569
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1570
        msg.msg_name = alloca(msg.msg_namelen);
1571
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1572
                                msg.msg_namelen);
1573
        if (ret) {
1574
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1575
            return ret;
1576
        }
1577
    } else {
1578
        msg.msg_name = NULL;
1579
        msg.msg_namelen = 0;
1580
    }
1581
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1582
    msg.msg_control = alloca(msg.msg_controllen);
1583
    msg.msg_flags = tswap32(msgp->msg_flags);
1584

    
1585
    count = tswapl(msgp->msg_iovlen);
1586
    vec = alloca(count * sizeof(struct iovec));
1587
    target_vec = tswapl(msgp->msg_iov);
1588
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1589
    msg.msg_iovlen = count;
1590
    msg.msg_iov = vec;
1591

    
1592
    if (send) {
1593
        ret = target_to_host_cmsg(&msg, msgp);
1594
        if (ret == 0)
1595
            ret = get_errno(sendmsg(fd, &msg, flags));
1596
    } else {
1597
        ret = get_errno(recvmsg(fd, &msg, flags));
1598
        if (!is_error(ret)) {
1599
            len = ret;
1600
            ret = host_to_target_cmsg(msgp, &msg);
1601
            if (!is_error(ret))
1602
                ret = len;
1603
        }
1604
    }
1605
    unlock_iovec(vec, target_vec, count, !send);
1606
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1607
    return ret;
1608
}
1609

    
1610
/* do_accept() Must return target values and target errnos. */
1611
static abi_long do_accept(int fd, abi_ulong target_addr,
1612
                          abi_ulong target_addrlen_addr)
1613
{
1614
    socklen_t addrlen;
1615
    void *addr;
1616
    abi_long ret;
1617

    
1618
    if (target_addr == 0)
1619
       return get_errno(accept(fd, NULL, NULL));
1620

    
1621
    /* linux returns EINVAL if addrlen pointer is invalid */
1622
    if (get_user_u32(addrlen, target_addrlen_addr))
1623
        return -TARGET_EINVAL;
1624

    
1625
    if (addrlen < 0)
1626
        return -TARGET_EINVAL;
1627

    
1628
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1629
        return -TARGET_EINVAL;
1630

    
1631
    addr = alloca(addrlen);
1632

    
1633
    ret = get_errno(accept(fd, addr, &addrlen));
1634
    if (!is_error(ret)) {
1635
        host_to_target_sockaddr(target_addr, addr, addrlen);
1636
        if (put_user_u32(addrlen, target_addrlen_addr))
1637
            ret = -TARGET_EFAULT;
1638
    }
1639
    return ret;
1640
}
1641

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

    
1650
    if (get_user_u32(addrlen, target_addrlen_addr))
1651
        return -TARGET_EFAULT;
1652

    
1653
    if (addrlen < 0)
1654
        return -TARGET_EINVAL;
1655

    
1656
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1657
        return -TARGET_EFAULT;
1658

    
1659
    addr = alloca(addrlen);
1660

    
1661
    ret = get_errno(getpeername(fd, addr, &addrlen));
1662
    if (!is_error(ret)) {
1663
        host_to_target_sockaddr(target_addr, addr, addrlen);
1664
        if (put_user_u32(addrlen, target_addrlen_addr))
1665
            ret = -TARGET_EFAULT;
1666
    }
1667
    return ret;
1668
}
1669

    
1670
/* do_getsockname() Must return target values and target errnos. */
1671
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1672
                               abi_ulong target_addrlen_addr)
1673
{
1674
    socklen_t addrlen;
1675
    void *addr;
1676
    abi_long ret;
1677

    
1678
    if (get_user_u32(addrlen, target_addrlen_addr))
1679
        return -TARGET_EFAULT;
1680

    
1681
    if (addrlen < 0)
1682
        return -TARGET_EINVAL;
1683

    
1684
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1685
        return -TARGET_EFAULT;
1686

    
1687
    addr = alloca(addrlen);
1688

    
1689
    ret = get_errno(getsockname(fd, addr, &addrlen));
1690
    if (!is_error(ret)) {
1691
        host_to_target_sockaddr(target_addr, addr, addrlen);
1692
        if (put_user_u32(addrlen, target_addrlen_addr))
1693
            ret = -TARGET_EFAULT;
1694
    }
1695
    return ret;
1696
}
1697

    
1698
/* do_socketpair() Must return target values and target errnos. */
1699
static abi_long do_socketpair(int domain, int type, int protocol,
1700
                              abi_ulong target_tab_addr)
1701
{
1702
    int tab[2];
1703
    abi_long ret;
1704

    
1705
    ret = get_errno(socketpair(domain, type, protocol, tab));
1706
    if (!is_error(ret)) {
1707
        if (put_user_s32(tab[0], target_tab_addr)
1708
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1709
            ret = -TARGET_EFAULT;
1710
    }
1711
    return ret;
1712
}
1713

    
1714
/* do_sendto() Must return target values and target errnos. */
1715
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1716
                          abi_ulong target_addr, socklen_t addrlen)
1717
{
1718
    void *addr;
1719
    void *host_msg;
1720
    abi_long ret;
1721

    
1722
    if (addrlen < 0)
1723
        return -TARGET_EINVAL;
1724

    
1725
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1726
    if (!host_msg)
1727
        return -TARGET_EFAULT;
1728
    if (target_addr) {
1729
        addr = alloca(addrlen);
1730
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1731
        if (ret) {
1732
            unlock_user(host_msg, msg, 0);
1733
            return ret;
1734
        }
1735
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1736
    } else {
1737
        ret = get_errno(send(fd, host_msg, len, flags));
1738
    }
1739
    unlock_user(host_msg, msg, 0);
1740
    return ret;
1741
}
1742

    
1743
/* do_recvfrom() Must return target values and target errnos. */
1744
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1745
                            abi_ulong target_addr,
1746
                            abi_ulong target_addrlen)
1747
{
1748
    socklen_t addrlen;
1749
    void *addr;
1750
    void *host_msg;
1751
    abi_long ret;
1752

    
1753
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1754
    if (!host_msg)
1755
        return -TARGET_EFAULT;
1756
    if (target_addr) {
1757
        if (get_user_u32(addrlen, target_addrlen)) {
1758
            ret = -TARGET_EFAULT;
1759
            goto fail;
1760
        }
1761
        if (addrlen < 0) {
1762
            ret = -TARGET_EINVAL;
1763
            goto fail;
1764
        }
1765
        addr = alloca(addrlen);
1766
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1767
    } else {
1768
        addr = NULL; /* To keep compiler quiet.  */
1769
        ret = get_errno(recv(fd, host_msg, len, flags));
1770
    }
1771
    if (!is_error(ret)) {
1772
        if (target_addr) {
1773
            host_to_target_sockaddr(target_addr, addr, addrlen);
1774
            if (put_user_u32(addrlen, target_addrlen)) {
1775
                ret = -TARGET_EFAULT;
1776
                goto fail;
1777
            }
1778
        }
1779
        unlock_user(host_msg, msg, len);
1780
    } else {
1781
fail:
1782
        unlock_user(host_msg, msg, 0);
1783
    }
1784
    return ret;
1785
}
1786

    
1787
#ifdef TARGET_NR_socketcall
1788
/* do_socketcall() Must return target values and target errnos. */
1789
static abi_long do_socketcall(int num, abi_ulong vptr)
1790
{
1791
    abi_long ret;
1792
    const int n = sizeof(abi_ulong);
1793

    
1794
    switch(num) {
1795
    case SOCKOP_socket:
1796
        {
1797
            abi_ulong domain, type, protocol;
1798

    
1799
            if (get_user_ual(domain, vptr)
1800
                || get_user_ual(type, vptr + n)
1801
                || get_user_ual(protocol, vptr + 2 * n))
1802
                return -TARGET_EFAULT;
1803

    
1804
            ret = do_socket(domain, type, protocol);
1805
        }
1806
        break;
1807
    case SOCKOP_bind:
1808
        {
1809
            abi_ulong sockfd;
1810
            abi_ulong target_addr;
1811
            socklen_t addrlen;
1812

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

    
1818
            ret = do_bind(sockfd, target_addr, addrlen);
1819
        }
1820
        break;
1821
    case SOCKOP_connect:
1822
        {
1823
            abi_ulong sockfd;
1824
            abi_ulong target_addr;
1825
            socklen_t addrlen;
1826

    
1827
            if (get_user_ual(sockfd, vptr)
1828
                || get_user_ual(target_addr, vptr + n)
1829
                || get_user_ual(addrlen, vptr + 2 * n))
1830
                return -TARGET_EFAULT;
1831

    
1832
            ret = do_connect(sockfd, target_addr, addrlen);
1833
        }
1834
        break;
1835
    case SOCKOP_listen:
1836
        {
1837
            abi_ulong sockfd, backlog;
1838

    
1839
            if (get_user_ual(sockfd, vptr)
1840
                || get_user_ual(backlog, vptr + n))
1841
                return -TARGET_EFAULT;
1842

    
1843
            ret = get_errno(listen(sockfd, backlog));
1844
        }
1845
        break;
1846
    case SOCKOP_accept:
1847
        {
1848
            abi_ulong sockfd;
1849
            abi_ulong target_addr, target_addrlen;
1850

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

    
1856
            ret = do_accept(sockfd, target_addr, target_addrlen);
1857
        }
1858
        break;
1859
    case SOCKOP_getsockname:
1860
        {
1861
            abi_ulong sockfd;
1862
            abi_ulong target_addr, target_addrlen;
1863

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

    
1869
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1870
        }
1871
        break;
1872
    case SOCKOP_getpeername:
1873
        {
1874
            abi_ulong sockfd;
1875
            abi_ulong target_addr, target_addrlen;
1876

    
1877
            if (get_user_ual(sockfd, vptr)
1878
                || get_user_ual(target_addr, vptr + n)
1879
                || get_user_ual(target_addrlen, vptr + 2 * n))
1880
                return -TARGET_EFAULT;
1881

    
1882
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1883
        }
1884
        break;
1885
    case SOCKOP_socketpair:
1886
        {
1887
            abi_ulong domain, type, protocol;
1888
            abi_ulong tab;
1889

    
1890
            if (get_user_ual(domain, vptr)
1891
                || get_user_ual(type, vptr + n)
1892
                || get_user_ual(protocol, vptr + 2 * n)
1893
                || get_user_ual(tab, vptr + 3 * n))
1894
                return -TARGET_EFAULT;
1895

    
1896
            ret = do_socketpair(domain, type, protocol, tab);
1897
        }
1898
        break;
1899
    case SOCKOP_send:
1900
        {
1901
            abi_ulong sockfd;
1902
            abi_ulong msg;
1903
            size_t len;
1904
            abi_ulong flags;
1905

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

    
1912
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1913
        }
1914
        break;
1915
    case SOCKOP_recv:
1916
        {
1917
            abi_ulong sockfd;
1918
            abi_ulong msg;
1919
            size_t len;
1920
            abi_ulong flags;
1921

    
1922
            if (get_user_ual(sockfd, vptr)
1923
                || get_user_ual(msg, vptr + n)
1924
                || get_user_ual(len, vptr + 2 * n)
1925
                || get_user_ual(flags, vptr + 3 * n))
1926
                return -TARGET_EFAULT;
1927

    
1928
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1929
        }
1930
        break;
1931
    case SOCKOP_sendto:
1932
        {
1933
            abi_ulong sockfd;
1934
            abi_ulong msg;
1935
            size_t len;
1936
            abi_ulong flags;
1937
            abi_ulong addr;
1938
            socklen_t addrlen;
1939

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

    
1948
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1949
        }
1950
        break;
1951
    case SOCKOP_recvfrom:
1952
        {
1953
            abi_ulong sockfd;
1954
            abi_ulong msg;
1955
            size_t len;
1956
            abi_ulong flags;
1957
            abi_ulong addr;
1958
            socklen_t addrlen;
1959

    
1960
            if (get_user_ual(sockfd, vptr)
1961
                || get_user_ual(msg, vptr + n)
1962
                || get_user_ual(len, vptr + 2 * n)
1963
                || get_user_ual(flags, vptr + 3 * n)
1964
                || get_user_ual(addr, vptr + 4 * n)
1965
                || get_user_ual(addrlen, vptr + 5 * n))
1966
                return -TARGET_EFAULT;
1967

    
1968
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1969
        }
1970
        break;
1971
    case SOCKOP_shutdown:
1972
        {
1973
            abi_ulong sockfd, how;
1974

    
1975
            if (get_user_ual(sockfd, vptr)
1976
                || get_user_ual(how, vptr + n))
1977
                return -TARGET_EFAULT;
1978

    
1979
            ret = get_errno(shutdown(sockfd, how));
1980
        }
1981
        break;
1982
    case SOCKOP_sendmsg:
1983
    case SOCKOP_recvmsg:
1984
        {
1985
            abi_ulong fd;
1986
            abi_ulong target_msg;
1987
            abi_ulong flags;
1988

    
1989
            if (get_user_ual(fd, vptr)
1990
                || get_user_ual(target_msg, vptr + n)
1991
                || get_user_ual(flags, vptr + 2 * n))
1992
                return -TARGET_EFAULT;
1993

    
1994
            ret = do_sendrecvmsg(fd, target_msg, flags,
1995
                                 (num == SOCKOP_sendmsg));
1996
        }
1997
        break;
1998
    case SOCKOP_setsockopt:
1999
        {
2000
            abi_ulong sockfd;
2001
            abi_ulong level;
2002
            abi_ulong optname;
2003
            abi_ulong optval;
2004
            socklen_t optlen;
2005

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

    
2013
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2014
        }
2015
        break;
2016
    case SOCKOP_getsockopt:
2017
        {
2018
            abi_ulong sockfd;
2019
            abi_ulong level;
2020
            abi_ulong optname;
2021
            abi_ulong optval;
2022
            socklen_t optlen;
2023

    
2024
            if (get_user_ual(sockfd, vptr)
2025
                || get_user_ual(level, vptr + n)
2026
                || get_user_ual(optname, vptr + 2 * n)
2027
                || get_user_ual(optval, vptr + 3 * n)
2028
                || get_user_ual(optlen, vptr + 4 * n))
2029
                return -TARGET_EFAULT;
2030

    
2031
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2032
        }
2033
        break;
2034
    default:
2035
        gemu_log("Unsupported socketcall: %d\n", num);
2036
        ret = -TARGET_ENOSYS;
2037
        break;
2038
    }
2039
    return ret;
2040
}
2041
#endif
2042

    
2043
#define N_SHM_REGIONS        32
2044

    
2045
static struct shm_region {
2046
    abi_ulong        start;
2047
    abi_ulong        size;
2048
} shm_regions[N_SHM_REGIONS];
2049

    
2050
struct target_ipc_perm
2051
{
2052
    abi_long __key;
2053
    abi_ulong uid;
2054
    abi_ulong gid;
2055
    abi_ulong cuid;
2056
    abi_ulong cgid;
2057
    unsigned short int mode;
2058
    unsigned short int __pad1;
2059
    unsigned short int __seq;
2060
    unsigned short int __pad2;
2061
    abi_ulong __unused1;
2062
    abi_ulong __unused2;
2063
};
2064

    
2065
struct target_semid_ds
2066
{
2067
  struct target_ipc_perm sem_perm;
2068
  abi_ulong sem_otime;
2069
  abi_ulong __unused1;
2070
  abi_ulong sem_ctime;
2071
  abi_ulong __unused2;
2072
  abi_ulong sem_nsems;
2073
  abi_ulong __unused3;
2074
  abi_ulong __unused4;
2075
};
2076

    
2077
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2078
                                               abi_ulong target_addr)
2079
{
2080
    struct target_ipc_perm *target_ip;
2081
    struct target_semid_ds *target_sd;
2082

    
2083
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2084
        return -TARGET_EFAULT;
2085
    target_ip = &(target_sd->sem_perm);
2086
    host_ip->__key = tswapl(target_ip->__key);
2087
    host_ip->uid = tswapl(target_ip->uid);
2088
    host_ip->gid = tswapl(target_ip->gid);
2089
    host_ip->cuid = tswapl(target_ip->cuid);
2090
    host_ip->cgid = tswapl(target_ip->cgid);
2091
    host_ip->mode = tswapl(target_ip->mode);
2092
    unlock_user_struct(target_sd, target_addr, 0);
2093
    return 0;
2094
}
2095

    
2096
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2097
                                               struct ipc_perm *host_ip)
2098
{
2099
    struct target_ipc_perm *target_ip;
2100
    struct target_semid_ds *target_sd;
2101

    
2102
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2103
        return -TARGET_EFAULT;
2104
    target_ip = &(target_sd->sem_perm);
2105
    target_ip->__key = tswapl(host_ip->__key);
2106
    target_ip->uid = tswapl(host_ip->uid);
2107
    target_ip->gid = tswapl(host_ip->gid);
2108
    target_ip->cuid = tswapl(host_ip->cuid);
2109
    target_ip->cgid = tswapl(host_ip->cgid);
2110
    target_ip->mode = tswapl(host_ip->mode);
2111
    unlock_user_struct(target_sd, target_addr, 1);
2112
    return 0;
2113
}
2114

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

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

    
2131
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2132
                                               struct semid_ds *host_sd)
2133
{
2134
    struct target_semid_ds *target_sd;
2135

    
2136
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2137
        return -TARGET_EFAULT;
2138
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2139
        return -TARGET_EFAULT;;
2140
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2141
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2142
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2143
    unlock_user_struct(target_sd, target_addr, 1);
2144
    return 0;
2145
}
2146

    
2147
struct target_seminfo {
2148
    int semmap;
2149
    int semmni;
2150
    int semmns;
2151
    int semmnu;
2152
    int semmsl;
2153
    int semopm;
2154
    int semume;
2155
    int semusz;
2156
    int semvmx;
2157
    int semaem;
2158
};
2159

    
2160
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2161
                                              struct seminfo *host_seminfo)
2162
{
2163
    struct target_seminfo *target_seminfo;
2164
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2165
        return -TARGET_EFAULT;
2166
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2167
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2168
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2169
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2170
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2171
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2172
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2173
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2174
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2175
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2176
    unlock_user_struct(target_seminfo, target_addr, 1);
2177
    return 0;
2178
}
2179

    
2180
union semun {
2181
        int val;
2182
        struct semid_ds *buf;
2183
        unsigned short *array;
2184
        struct seminfo *__buf;
2185
};
2186

    
2187
union target_semun {
2188
        int val;
2189
        abi_ulong buf;
2190
        abi_ulong array;
2191
        abi_ulong __buf;
2192
};
2193

    
2194
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2195
                                               abi_ulong target_addr)
2196
{
2197
    int nsems;
2198
    unsigned short *array;
2199
    union semun semun;
2200
    struct semid_ds semid_ds;
2201
    int i, ret;
2202

    
2203
    semun.buf = &semid_ds;
2204

    
2205
    ret = semctl(semid, 0, IPC_STAT, semun);
2206
    if (ret == -1)
2207
        return get_errno(ret);
2208

    
2209
    nsems = semid_ds.sem_nsems;
2210

    
2211
    *host_array = malloc(nsems*sizeof(unsigned short));
2212
    array = lock_user(VERIFY_READ, target_addr,
2213
                      nsems*sizeof(unsigned short), 1);
2214
    if (!array)
2215
        return -TARGET_EFAULT;
2216

    
2217
    for(i=0; i<nsems; i++) {
2218
        __get_user((*host_array)[i], &array[i]);
2219
    }
2220
    unlock_user(array, target_addr, 0);
2221

    
2222
    return 0;
2223
}
2224

    
2225
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2226
                                               unsigned short **host_array)
2227
{
2228
    int nsems;
2229
    unsigned short *array;
2230
    union semun semun;
2231
    struct semid_ds semid_ds;
2232
    int i, ret;
2233

    
2234
    semun.buf = &semid_ds;
2235

    
2236
    ret = semctl(semid, 0, IPC_STAT, semun);
2237
    if (ret == -1)
2238
        return get_errno(ret);
2239

    
2240
    nsems = semid_ds.sem_nsems;
2241

    
2242
    array = lock_user(VERIFY_WRITE, target_addr,
2243
                      nsems*sizeof(unsigned short), 0);
2244
    if (!array)
2245
        return -TARGET_EFAULT;
2246

    
2247
    for(i=0; i<nsems; i++) {
2248
        __put_user((*host_array)[i], &array[i]);
2249
    }
2250
    free(*host_array);
2251
    unlock_user(array, target_addr, 1);
2252

    
2253
    return 0;
2254
}
2255

    
2256
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2257
                                 union target_semun target_su)
2258
{
2259
    union semun arg;
2260
    struct semid_ds dsarg;
2261
    unsigned short *array = NULL;
2262
    struct seminfo seminfo;
2263
    abi_long ret = -TARGET_EINVAL;
2264
    abi_long err;
2265
    cmd &= 0xff;
2266

    
2267
    switch( cmd ) {
2268
        case GETVAL:
2269
        case SETVAL:
2270
            arg.val = tswapl(target_su.val);
2271
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2272
            target_su.val = tswapl(arg.val);
2273
            break;
2274
        case GETALL:
2275
        case SETALL:
2276
            err = target_to_host_semarray(semid, &array, target_su.array);
2277
            if (err)
2278
                return err;
2279
            arg.array = array;
2280
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2281
            err = host_to_target_semarray(semid, target_su.array, &array);
2282
            if (err)
2283
                return err;
2284
            break;
2285
        case IPC_STAT:
2286
        case IPC_SET:
2287
        case SEM_STAT:
2288
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2289
            if (err)
2290
                return err;
2291
            arg.buf = &dsarg;
2292
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2293
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2294
            if (err)
2295
                return err;
2296
            break;
2297
        case IPC_INFO:
2298
        case SEM_INFO:
2299
            arg.__buf = &seminfo;
2300
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2301
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2302
            if (err)
2303
                return err;
2304
            break;
2305
        case IPC_RMID:
2306
        case GETPID:
2307
        case GETNCNT:
2308
        case GETZCNT:
2309
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2310
            break;
2311
    }
2312

    
2313
    return ret;
2314
}
2315

    
2316
struct target_sembuf {
2317
    unsigned short sem_num;
2318
    short sem_op;
2319
    short sem_flg;
2320
};
2321

    
2322
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2323
                                             abi_ulong target_addr,
2324
                                             unsigned nsops)
2325
{
2326
    struct target_sembuf *target_sembuf;
2327
    int i;
2328

    
2329
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2330
                              nsops*sizeof(struct target_sembuf), 1);
2331
    if (!target_sembuf)
2332
        return -TARGET_EFAULT;
2333

    
2334
    for(i=0; i<nsops; i++) {
2335
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2336
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2337
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2338
    }
2339

    
2340
    unlock_user(target_sembuf, target_addr, 0);
2341

    
2342
    return 0;
2343
}
2344

    
2345
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2346
{
2347
    struct sembuf sops[nsops];
2348

    
2349
    if (target_to_host_sembuf(sops, ptr, nsops))
2350
        return -TARGET_EFAULT;
2351

    
2352
    return semop(semid, sops, nsops);
2353
}
2354

    
2355
struct target_msqid_ds
2356
{
2357
    struct target_ipc_perm msg_perm;
2358
    abi_ulong msg_stime;
2359
#if TARGET_ABI_BITS == 32
2360
    abi_ulong __unused1;
2361
#endif
2362
    abi_ulong msg_rtime;
2363
#if TARGET_ABI_BITS == 32
2364
    abi_ulong __unused2;
2365
#endif
2366
    abi_ulong msg_ctime;
2367
#if TARGET_ABI_BITS == 32
2368
    abi_ulong __unused3;
2369
#endif
2370
    abi_ulong __msg_cbytes;
2371
    abi_ulong msg_qnum;
2372
    abi_ulong msg_qbytes;
2373
    abi_ulong msg_lspid;
2374
    abi_ulong msg_lrpid;
2375
    abi_ulong __unused4;
2376
    abi_ulong __unused5;
2377
};
2378

    
2379
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2380
                                               abi_ulong target_addr)
2381
{
2382
    struct target_msqid_ds *target_md;
2383

    
2384
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2385
        return -TARGET_EFAULT;
2386
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2387
        return -TARGET_EFAULT;
2388
    host_md->msg_stime = tswapl(target_md->msg_stime);
2389
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2390
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2391
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2392
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2393
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2394
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2395
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2396
    unlock_user_struct(target_md, target_addr, 0);
2397
    return 0;
2398
}
2399

    
2400
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2401
                                               struct msqid_ds *host_md)
2402
{
2403
    struct target_msqid_ds *target_md;
2404

    
2405
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2406
        return -TARGET_EFAULT;
2407
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2408
        return -TARGET_EFAULT;
2409
    target_md->msg_stime = tswapl(host_md->msg_stime);
2410
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2411
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2412
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2413
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2414
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2415
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2416
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2417
    unlock_user_struct(target_md, target_addr, 1);
2418
    return 0;
2419
}
2420

    
2421
struct target_msginfo {
2422
    int msgpool;
2423
    int msgmap;
2424
    int msgmax;
2425
    int msgmnb;
2426
    int msgmni;
2427
    int msgssz;
2428
    int msgtql;
2429
    unsigned short int msgseg;
2430
};
2431

    
2432
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2433
                                              struct msginfo *host_msginfo)
2434
{
2435
    struct target_msginfo *target_msginfo;
2436
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2437
        return -TARGET_EFAULT;
2438
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2439
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2440
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2441
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2442
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2443
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2444
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2445
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2446
    unlock_user_struct(target_msginfo, target_addr, 1);
2447
    return 0;
2448
}
2449

    
2450
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2451
{
2452
    struct msqid_ds dsarg;
2453
    struct msginfo msginfo;
2454
    abi_long ret = -TARGET_EINVAL;
2455

    
2456
    cmd &= 0xff;
2457

    
2458
    switch (cmd) {
2459
    case IPC_STAT:
2460
    case IPC_SET:
2461
    case MSG_STAT:
2462
        if (target_to_host_msqid_ds(&dsarg,ptr))
2463
            return -TARGET_EFAULT;
2464
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2465
        if (host_to_target_msqid_ds(ptr,&dsarg))
2466
            return -TARGET_EFAULT;
2467
        break;
2468
    case IPC_RMID:
2469
        ret = get_errno(msgctl(msgid, cmd, NULL));
2470
        break;
2471
    case IPC_INFO:
2472
    case MSG_INFO:
2473
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2474
        if (host_to_target_msginfo(ptr, &msginfo))
2475
            return -TARGET_EFAULT;
2476
        break;
2477
    }
2478

    
2479
    return ret;
2480
}
2481

    
2482
struct target_msgbuf {
2483
    abi_long mtype;
2484
    char        mtext[1];
2485
};
2486

    
2487
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2488
                                 unsigned int msgsz, int msgflg)
2489
{
2490
    struct target_msgbuf *target_mb;
2491
    struct msgbuf *host_mb;
2492
    abi_long ret = 0;
2493

    
2494
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2495
        return -TARGET_EFAULT;
2496
    host_mb = malloc(msgsz+sizeof(long));
2497
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2498
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2499
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2500
    free(host_mb);
2501
    unlock_user_struct(target_mb, msgp, 0);
2502

    
2503
    return ret;
2504
}
2505

    
2506
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2507
                                 unsigned int msgsz, abi_long msgtyp,
2508
                                 int msgflg)
2509
{
2510
    struct target_msgbuf *target_mb;
2511
    char *target_mtext;
2512
    struct msgbuf *host_mb;
2513
    abi_long ret = 0;
2514

    
2515
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2516
        return -TARGET_EFAULT;
2517

    
2518
    host_mb = malloc(msgsz+sizeof(long));
2519
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2520

    
2521
    if (ret > 0) {
2522
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2523
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2524
        if (!target_mtext) {
2525
            ret = -TARGET_EFAULT;
2526
            goto end;
2527
        }
2528
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2529
        unlock_user(target_mtext, target_mtext_addr, ret);
2530
    }
2531

    
2532
    target_mb->mtype = tswapl(host_mb->mtype);
2533
    free(host_mb);
2534

    
2535
end:
2536
    if (target_mb)
2537
        unlock_user_struct(target_mb, msgp, 1);
2538
    return ret;
2539
}
2540

    
2541
struct target_shmid_ds
2542
{
2543
    struct target_ipc_perm shm_perm;
2544
    abi_ulong shm_segsz;
2545
    abi_ulong shm_atime;
2546
#if TARGET_ABI_BITS == 32
2547
    abi_ulong __unused1;
2548
#endif
2549
    abi_ulong shm_dtime;
2550
#if TARGET_ABI_BITS == 32
2551
    abi_ulong __unused2;
2552
#endif
2553
    abi_ulong shm_ctime;
2554
#if TARGET_ABI_BITS == 32
2555
    abi_ulong __unused3;
2556
#endif
2557
    int shm_cpid;
2558
    int shm_lpid;
2559
    abi_ulong shm_nattch;
2560
    unsigned long int __unused4;
2561
    unsigned long int __unused5;
2562
};
2563

    
2564
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2565
                                               abi_ulong target_addr)
2566
{
2567
    struct target_shmid_ds *target_sd;
2568

    
2569
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2570
        return -TARGET_EFAULT;
2571
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2572
        return -TARGET_EFAULT;
2573
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2574
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2575
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2576
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2577
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2578
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2579
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2580
    unlock_user_struct(target_sd, target_addr, 0);
2581
    return 0;
2582
}
2583

    
2584
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2585
                                               struct shmid_ds *host_sd)
2586
{
2587
    struct target_shmid_ds *target_sd;
2588

    
2589
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2590
        return -TARGET_EFAULT;
2591
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2592
        return -TARGET_EFAULT;
2593
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2594
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2595
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2596
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2597
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2598
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2599
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2600
    unlock_user_struct(target_sd, target_addr, 1);
2601
    return 0;
2602
}
2603

    
2604
struct  target_shminfo {
2605
    abi_ulong shmmax;
2606
    abi_ulong shmmin;
2607
    abi_ulong shmmni;
2608
    abi_ulong shmseg;
2609
    abi_ulong shmall;
2610
};
2611

    
2612
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2613
                                              struct shminfo *host_shminfo)
2614
{
2615
    struct target_shminfo *target_shminfo;
2616
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2617
        return -TARGET_EFAULT;
2618
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2619
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2620
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2621
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2622
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2623
    unlock_user_struct(target_shminfo, target_addr, 1);
2624
    return 0;
2625
}
2626

    
2627
struct target_shm_info {
2628
    int used_ids;
2629
    abi_ulong shm_tot;
2630
    abi_ulong shm_rss;
2631
    abi_ulong shm_swp;
2632
    abi_ulong swap_attempts;
2633
    abi_ulong swap_successes;
2634
};
2635

    
2636
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2637
                                               struct shm_info *host_shm_info)
2638
{
2639
    struct target_shm_info *target_shm_info;
2640
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2641
        return -TARGET_EFAULT;
2642
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2643
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2644
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2645
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2646
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2647
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2648
    unlock_user_struct(target_shm_info, target_addr, 1);
2649
    return 0;
2650
}
2651

    
2652
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2653
{
2654
    struct shmid_ds dsarg;
2655
    struct shminfo shminfo;
2656
    struct shm_info shm_info;
2657
    abi_long ret = -TARGET_EINVAL;
2658

    
2659
    cmd &= 0xff;
2660

    
2661
    switch(cmd) {
2662
    case IPC_STAT:
2663
    case IPC_SET:
2664
    case SHM_STAT:
2665
        if (target_to_host_shmid_ds(&dsarg, buf))
2666
            return -TARGET_EFAULT;
2667
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2668
        if (host_to_target_shmid_ds(buf, &dsarg))
2669
            return -TARGET_EFAULT;
2670
        break;
2671
    case IPC_INFO:
2672
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2673
        if (host_to_target_shminfo(buf, &shminfo))
2674
            return -TARGET_EFAULT;
2675
        break;
2676
    case SHM_INFO:
2677
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2678
        if (host_to_target_shm_info(buf, &shm_info))
2679
            return -TARGET_EFAULT;
2680
        break;
2681
    case IPC_RMID:
2682
    case SHM_LOCK:
2683
    case SHM_UNLOCK:
2684
        ret = get_errno(shmctl(shmid, cmd, NULL));
2685
        break;
2686
    }
2687

    
2688
    return ret;
2689
}
2690

    
2691
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2692
{
2693
    abi_long raddr;
2694
    void *host_raddr;
2695
    struct shmid_ds shm_info;
2696
    int i,ret;
2697

    
2698
    /* find out the length of the shared memory segment */
2699
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2700
    if (is_error(ret)) {
2701
        /* can't get length, bail out */
2702
        return ret;
2703
    }
2704

    
2705
    mmap_lock();
2706

    
2707
    if (shmaddr)
2708
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2709
    else {
2710
        abi_ulong mmap_start;
2711

    
2712
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2713

    
2714
        if (mmap_start == -1) {
2715
            errno = ENOMEM;
2716
            host_raddr = (void *)-1;
2717
        } else
2718
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2719
    }
2720

    
2721
    if (host_raddr == (void *)-1) {
2722
        mmap_unlock();
2723
        return get_errno((long)host_raddr);
2724
    }
2725
    raddr=h2g((unsigned long)host_raddr);
2726

    
2727
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2728
                   PAGE_VALID | PAGE_READ |
2729
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2730

    
2731
    for (i = 0; i < N_SHM_REGIONS; i++) {
2732
        if (shm_regions[i].start == 0) {
2733
            shm_regions[i].start = raddr;
2734
            shm_regions[i].size = shm_info.shm_segsz;
2735
            break;
2736
        }
2737
    }
2738

    
2739
    mmap_unlock();
2740
    return raddr;
2741

    
2742
}
2743

    
2744
static inline abi_long do_shmdt(abi_ulong shmaddr)
2745
{
2746
    int i;
2747

    
2748
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2749
        if (shm_regions[i].start == shmaddr) {
2750
            shm_regions[i].start = 0;
2751
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2752
            break;
2753
        }
2754
    }
2755

    
2756
    return get_errno(shmdt(g2h(shmaddr)));
2757
}
2758

    
2759
#ifdef TARGET_NR_ipc
2760
/* ??? This only works with linear mappings.  */
2761
/* do_ipc() must return target values and target errnos. */
2762
static abi_long do_ipc(unsigned int call, int first,
2763
                       int second, int third,
2764
                       abi_long ptr, abi_long fifth)
2765
{
2766
    int version;
2767
    abi_long ret = 0;
2768

    
2769
    version = call >> 16;
2770
    call &= 0xffff;
2771

    
2772
    switch (call) {
2773
    case IPCOP_semop:
2774
        ret = do_semop(first, ptr, second);
2775
        break;
2776

    
2777
    case IPCOP_semget:
2778
        ret = get_errno(semget(first, second, third));
2779
        break;
2780

    
2781
    case IPCOP_semctl:
2782
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2783
        break;
2784

    
2785
    case IPCOP_msgget:
2786
        ret = get_errno(msgget(first, second));
2787
        break;
2788

    
2789
    case IPCOP_msgsnd:
2790
        ret = do_msgsnd(first, ptr, second, third);
2791
        break;
2792

    
2793
    case IPCOP_msgctl:
2794
        ret = do_msgctl(first, second, ptr);
2795
        break;
2796

    
2797
    case IPCOP_msgrcv:
2798
        switch (version) {
2799
        case 0:
2800
            {
2801
                struct target_ipc_kludge {
2802
                    abi_long msgp;
2803
                    abi_long msgtyp;
2804
                } *tmp;
2805

    
2806
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2807
                    ret = -TARGET_EFAULT;
2808
                    break;
2809
                }
2810

    
2811
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2812

    
2813
                unlock_user_struct(tmp, ptr, 0);
2814
                break;
2815
            }
2816
        default:
2817
            ret = do_msgrcv(first, ptr, second, fifth, third);
2818
        }
2819
        break;
2820

    
2821
    case IPCOP_shmat:
2822
        switch (version) {
2823
        default:
2824
        {
2825
            abi_ulong raddr;
2826
            raddr = do_shmat(first, ptr, second);
2827
            if (is_error(raddr))
2828
                return get_errno(raddr);
2829
            if (put_user_ual(raddr, third))
2830
                return -TARGET_EFAULT;
2831
            break;
2832
        }
2833
        case 1:
2834
            ret = -TARGET_EINVAL;
2835
            break;
2836
        }
2837
        break;
2838
    case IPCOP_shmdt:
2839
        ret = do_shmdt(ptr);
2840
        break;
2841

    
2842
    case IPCOP_shmget:
2843
        /* IPC_* flag values are the same on all linux platforms */
2844
        ret = get_errno(shmget(first, second, third));
2845
        break;
2846

    
2847
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2848
    case IPCOP_shmctl:
2849
        ret = do_shmctl(first, second, third);
2850
        break;
2851
    default:
2852
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2853
        ret = -TARGET_ENOSYS;
2854
        break;
2855
    }
2856
    return ret;
2857
}
2858
#endif
2859

    
2860
/* kernel structure types definitions */
2861
#define IFNAMSIZ        16
2862

    
2863
#define STRUCT(name, ...) STRUCT_ ## name,
2864
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2865
enum {
2866
#include "syscall_types.h"
2867
};
2868
#undef STRUCT
2869
#undef STRUCT_SPECIAL
2870

    
2871
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2872
#define STRUCT_SPECIAL(name)
2873
#include "syscall_types.h"
2874
#undef STRUCT
2875
#undef STRUCT_SPECIAL
2876

    
2877
typedef struct IOCTLEntry {
2878
    unsigned int target_cmd;
2879
    unsigned int host_cmd;
2880
    const char *name;
2881
    int access;
2882
    const argtype arg_type[5];
2883
} IOCTLEntry;
2884

    
2885
#define IOC_R 0x0001
2886
#define IOC_W 0x0002
2887
#define IOC_RW (IOC_R | IOC_W)
2888

    
2889
#define MAX_STRUCT_SIZE 4096
2890

    
2891
static IOCTLEntry ioctl_entries[] = {
2892
#define IOCTL(cmd, access, ...) \
2893
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2894
#include "ioctls.h"
2895
    { 0, 0, },
2896
};
2897

    
2898
/* ??? Implement proper locking for ioctls.  */
2899
/* do_ioctl() Must return target values and target errnos. */
2900
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2901
{
2902
    const IOCTLEntry *ie;
2903
    const argtype *arg_type;
2904
    abi_long ret;
2905
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2906
    int target_size;
2907
    void *argptr;
2908

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

    
2982
static const bitmask_transtbl iflag_tbl[] = {
2983
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2984
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2985
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2986
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2987
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2988
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2989
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2990
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2991
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2992
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2993
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2994
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2995
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2996
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2997
        { 0, 0, 0, 0 }
2998
};
2999

    
3000
static const bitmask_transtbl oflag_tbl[] = {
3001
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3002
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3003
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3004
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3005
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3006
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3007
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3008
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3009
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3010
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3011
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3012
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3013
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3014
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3015
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3016
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3017
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3018
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3019
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3020
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3021
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3022
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3023
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3024
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3025
        { 0, 0, 0, 0 }
3026
};
3027

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

    
3063
static const bitmask_transtbl lflag_tbl[] = {
3064
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3065
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3066
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3067
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3068
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3069
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3070
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3071
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3072
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3073
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3074
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3075
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3076
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3077
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3078
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3079
        { 0, 0, 0, 0 }
3080
};
3081

    
3082
static void target_to_host_termios (void *dst, const void *src)
3083
{
3084
    struct host_termios *host = dst;
3085
    const struct target_termios *target = src;
3086

    
3087
    host->c_iflag =
3088
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3089
    host->c_oflag =
3090
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3091
    host->c_cflag =
3092
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3093
    host->c_lflag =
3094
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3095
    host->c_line = target->c_line;
3096

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

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

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

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

    
3152
static const StructEntry struct_termios_def = {
3153
    .convert = { host_to_target_termios, target_to_host_termios },
3154
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3155
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3156
};
3157

    
3158
static bitmask_transtbl mmap_flags_tbl[] = {
3159
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3160
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3161
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3162
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3163
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3164
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3165
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3166
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3167
        { 0, 0, 0, 0 }
3168
};
3169

    
3170
#if defined(TARGET_I386)
3171

    
3172
/* NOTE: there is really one LDT for all the threads */
3173
static uint8_t *ldt_table;
3174

    
3175
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3176
{
3177
    int size;
3178
    void *p;
3179

    
3180
    if (!ldt_table)
3181
        return 0;
3182
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3183
    if (size > bytecount)
3184
        size = bytecount;
3185
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3186
    if (!p)
3187
        return -TARGET_EFAULT;
3188
    /* ??? Should this by byteswapped?  */
3189
    memcpy(p, ldt_table, size);
3190
    unlock_user(p, ptr, size);
3191
    return size;
3192
}
3193

    
3194
/* XXX: add locking support */
3195
static abi_long write_ldt(CPUX86State *env,
3196
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3197
{
3198
    struct target_modify_ldt_ldt_s ldt_info;
3199
    struct target_modify_ldt_ldt_s *target_ldt_info;
3200
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3201
    int seg_not_present, useable, lm;
3202
    uint32_t *lp, entry_1, entry_2;
3203

    
3204
    if (bytecount != sizeof(ldt_info))
3205
        return -TARGET_EINVAL;
3206
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3207
        return -TARGET_EFAULT;
3208
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3209
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3210
    ldt_info.limit = tswap32(target_ldt_info->limit);
3211
    ldt_info.flags = tswap32(target_ldt_info->flags);
3212
    unlock_user_struct(target_ldt_info, ptr, 0);
3213

    
3214
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3215
        return -TARGET_EINVAL;
3216
    seg_32bit = ldt_info.flags & 1;
3217
    contents = (ldt_info.flags >> 1) & 3;
3218
    read_exec_only = (ldt_info.flags >> 3) & 1;
3219
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3220
    seg_not_present = (ldt_info.flags >> 5) & 1;
3221
    useable = (ldt_info.flags >> 6) & 1;
3222
#ifdef TARGET_ABI32
3223
    lm = 0;
3224
#else
3225
    lm = (ldt_info.flags >> 7) & 1;
3226
#endif
3227
    if (contents == 3) {
3228
        if (oldmode)
3229
            return -TARGET_EINVAL;
3230
        if (seg_not_present == 0)
3231
            return -TARGET_EINVAL;
3232
    }
3233
    /* allocate the LDT */
3234
    if (!ldt_table) {
3235
        env->ldt.base = target_mmap(0,
3236
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3237
                                    PROT_READ|PROT_WRITE,
3238
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3239
        if (env->ldt.base == -1)
3240
            return -TARGET_ENOMEM;
3241
        memset(g2h(env->ldt.base), 0,
3242
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3243
        env->ldt.limit = 0xffff;
3244
        ldt_table = g2h(env->ldt.base);
3245
    }
3246

    
3247
    /* NOTE: same code as Linux kernel */
3248
    /* Allow LDTs to be cleared by the user. */
3249
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3250
        if (oldmode ||
3251
            (contents == 0                &&
3252
             read_exec_only == 1        &&
3253
             seg_32bit == 0                &&
3254
             limit_in_pages == 0        &&
3255
             seg_not_present == 1        &&
3256
             useable == 0 )) {
3257
            entry_1 = 0;
3258
            entry_2 = 0;
3259
            goto install;
3260
        }
3261
    }
3262

    
3263
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3264
        (ldt_info.limit & 0x0ffff);
3265
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3266
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3267
        (ldt_info.limit & 0xf0000) |
3268
        ((read_exec_only ^ 1) << 9) |
3269
        (contents << 10) |
3270
        ((seg_not_present ^ 1) << 15) |
3271
        (seg_32bit << 22) |
3272
        (limit_in_pages << 23) |
3273
        (lm << 21) |
3274
        0x7000;
3275
    if (!oldmode)
3276
        entry_2 |= (useable << 20);
3277

    
3278
    /* Install the new entry ...  */
3279
install:
3280
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3281
    lp[0] = tswap32(entry_1);
3282
    lp[1] = tswap32(entry_2);
3283
    return 0;
3284
}
3285

    
3286
/* specific and weird i386 syscalls */
3287
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3288
                              unsigned long bytecount)
3289
{
3290
    abi_long ret;
3291

    
3292
    switch (func) {
3293
    case 0:
3294
        ret = read_ldt(ptr, bytecount);
3295
        break;
3296
    case 1:
3297
        ret = write_ldt(env, ptr, bytecount, 1);
3298
        break;
3299
    case 0x11:
3300
        ret = write_ldt(env, ptr, bytecount, 0);
3301
        break;
3302
    default:
3303
        ret = -TARGET_ENOSYS;
3304
        break;
3305
    }
3306
    return ret;
3307
}
3308

    
3309
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3310
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3311
{
3312
    uint64_t *gdt_table = g2h(env->gdt.base);
3313
    struct target_modify_ldt_ldt_s ldt_info;
3314
    struct target_modify_ldt_ldt_s *target_ldt_info;
3315
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3316
    int seg_not_present, useable, lm;
3317
    uint32_t *lp, entry_1, entry_2;
3318
    int i;
3319

    
3320
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3321
    if (!target_ldt_info)
3322
        return -TARGET_EFAULT;
3323
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3324
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3325
    ldt_info.limit = tswap32(target_ldt_info->limit);
3326
    ldt_info.flags = tswap32(target_ldt_info->flags);
3327
    if (ldt_info.entry_number == -1) {
3328
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3329
            if (gdt_table[i] == 0) {
3330
                ldt_info.entry_number = i;
3331
                target_ldt_info->entry_number = tswap32(i);
3332
                break;
3333
            }
3334
        }
3335
    }
3336
    unlock_user_struct(target_ldt_info, ptr, 1);
3337

    
3338
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3339
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3340
           return -TARGET_EINVAL;
3341
    seg_32bit = ldt_info.flags & 1;
3342
    contents = (ldt_info.flags >> 1) & 3;
3343
    read_exec_only = (ldt_info.flags >> 3) & 1;
3344
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3345
    seg_not_present = (ldt_info.flags >> 5) & 1;
3346
    useable = (ldt_info.flags >> 6) & 1;
3347
#ifdef TARGET_ABI32
3348
    lm = 0;
3349
#else
3350
    lm = (ldt_info.flags >> 7) & 1;
3351
#endif
3352

    
3353
    if (contents == 3) {
3354
        if (seg_not_present == 0)
3355
            return -TARGET_EINVAL;
3356
    }
3357

    
3358
    /* NOTE: same code as Linux kernel */
3359
    /* Allow LDTs to be cleared by the user. */
3360
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3361
        if ((contents == 0             &&
3362
             read_exec_only == 1       &&
3363
             seg_32bit == 0            &&
3364
             limit_in_pages == 0       &&
3365
             seg_not_present == 1      &&
3366
             useable == 0 )) {
3367
            entry_1 = 0;
3368
            entry_2 = 0;
3369
            goto install;
3370
        }
3371
    }
3372

    
3373
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3374
        (ldt_info.limit & 0x0ffff);
3375
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3376
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3377
        (ldt_info.limit & 0xf0000) |
3378
        ((read_exec_only ^ 1) << 9) |
3379
        (contents << 10) |
3380
        ((seg_not_present ^ 1) << 15) |
3381
        (seg_32bit << 22) |
3382
        (limit_in_pages << 23) |
3383
        (useable << 20) |
3384
        (lm << 21) |
3385
        0x7000;
3386

    
3387
    /* Install the new entry ...  */
3388
install:
3389
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3390
    lp[0] = tswap32(entry_1);
3391
    lp[1] = tswap32(entry_2);
3392
    return 0;
3393
}
3394

    
3395
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3396
{
3397
    struct target_modify_ldt_ldt_s *target_ldt_info;
3398
    uint64_t *gdt_table = g2h(env->gdt.base);
3399
    uint32_t base_addr, limit, flags;
3400
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3401
    int seg_not_present, useable, lm;
3402
    uint32_t *lp, entry_1, entry_2;
3403

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

    
3443
#ifndef TARGET_ABI32
3444
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3445
{
3446
    abi_long ret;
3447
    abi_ulong val;
3448
    int idx;
3449
    
3450
    switch(code) {
3451
    case TARGET_ARCH_SET_GS:
3452
    case TARGET_ARCH_SET_FS:
3453
        if (code == TARGET_ARCH_SET_GS)
3454
            idx = R_GS;
3455
        else
3456
            idx = R_FS;
3457
        cpu_x86_load_seg(env, idx, 0);
3458
        env->segs[idx].base = addr;
3459
        break;
3460
    case TARGET_ARCH_GET_GS:
3461
    case TARGET_ARCH_GET_FS:
3462
        if (code == TARGET_ARCH_GET_GS)
3463
            idx = R_GS;
3464
        else
3465
            idx = R_FS;
3466
        val = env->segs[idx].base;
3467
        if (put_user(val, addr, abi_ulong))
3468
            return -TARGET_EFAULT;
3469
        break;
3470
    default:
3471
        ret = -TARGET_EINVAL;
3472
        break;
3473
    }
3474
    return 0;
3475
}
3476
#endif
3477

    
3478
#endif /* defined(TARGET_I386) */
3479

    
3480
#if defined(CONFIG_USE_NPTL)
3481

    
3482
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3483

    
3484
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3485
typedef struct {
3486
    CPUState *env;
3487
    pthread_mutex_t mutex;
3488
    pthread_cond_t cond;
3489
    pthread_t thread;
3490
    uint32_t tid;
3491
    abi_ulong child_tidptr;
3492
    abi_ulong parent_tidptr;
3493
    sigset_t sigmask;
3494
} new_thread_info;
3495

    
3496
static void *clone_func(void *arg)
3497
{
3498
    new_thread_info *info = arg;
3499
    CPUState *env;
3500
    TaskState *ts;
3501

    
3502
    env = info->env;
3503
    thread_env = env;
3504
    ts = (TaskState *)thread_env->opaque;
3505
    info->tid = gettid();
3506
    env->host_tid = info->tid;
3507
    task_settid(ts);
3508
    if (info->child_tidptr)
3509
        put_user_u32(info->tid, info->child_tidptr);
3510
    if (info->parent_tidptr)
3511
        put_user_u32(info->tid, info->parent_tidptr);
3512
    /* Enable signals.  */
3513
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3514
    /* Signal to the parent that we're ready.  */
3515
    pthread_mutex_lock(&info->mutex);
3516
    pthread_cond_broadcast(&info->cond);
3517
    pthread_mutex_unlock(&info->mutex);
3518
    /* Wait until the parent has finshed initializing the tls state.  */
3519
    pthread_mutex_lock(&clone_lock);
3520
    pthread_mutex_unlock(&clone_lock);
3521
    cpu_loop(env);
3522
    /* never exits */
3523
    return NULL;
3524
}
3525
#else
3526
/* this stack is the equivalent of the kernel stack associated with a
3527
   thread/process */
3528
#define NEW_STACK_SIZE 8192
3529

    
3530
static int clone_func(void *arg)
3531
{
3532
    CPUState *env = arg;
3533
    cpu_loop(env);
3534
    /* never exits */
3535
    return 0;
3536
}
3537
#endif
3538

    
3539
/* do_fork() Must return host values and target errnos (unlike most
3540
   do_*() functions). */
3541
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3542
                   abi_ulong parent_tidptr, target_ulong newtls,
3543
                   abi_ulong child_tidptr)
3544
{
3545
    int ret;
3546
    TaskState *ts;
3547
    uint8_t *new_stack;
3548
    CPUState *new_env;
3549
#if defined(CONFIG_USE_NPTL)
3550
    unsigned int nptl_flags;
3551
    sigset_t sigmask;
3552
#endif
3553

    
3554
    /* Emulate vfork() with fork() */
3555
    if (flags & CLONE_VFORK)
3556
        flags &= ~(CLONE_VFORK | CLONE_VM);
3557

    
3558
    if (flags & CLONE_VM) {
3559
        TaskState *parent_ts = (TaskState *)env->opaque;
3560
#if defined(CONFIG_USE_NPTL)
3561
        new_thread_info info;
3562
        pthread_attr_t attr;
3563
#endif
3564
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3565
        init_task_state(ts);
3566
        new_stack = ts->stack;
3567
        /* we create a new CPU instance. */
3568
        new_env = cpu_copy(env);
3569
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3570
        cpu_reset(new_env);
3571
#endif
3572
        /* Init regs that differ from the parent.  */
3573
        cpu_clone_regs(new_env, newsp);
3574
        new_env->opaque = ts;
3575
        ts->bprm = parent_ts->bprm;
3576
        ts->info = parent_ts->info;
3577
#if defined(CONFIG_USE_NPTL)
3578
        nptl_flags = flags;
3579
        flags &= ~CLONE_NPTL_FLAGS2;
3580

    
3581
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3582
            ts->child_tidptr = child_tidptr;
3583
        }
3584

    
3585
        if (nptl_flags & CLONE_SETTLS)
3586
            cpu_set_tls (new_env, newtls);
3587

    
3588
        /* Grab a mutex so that thread setup appears atomic.  */
3589
        pthread_mutex_lock(&clone_lock);
3590

    
3591
        memset(&info, 0, sizeof(info));
3592
        pthread_mutex_init(&info.mutex, NULL);
3593
        pthread_mutex_lock(&info.mutex);
3594
        pthread_cond_init(&info.cond, NULL);
3595
        info.env = new_env;
3596
        if (nptl_flags & CLONE_CHILD_SETTID)
3597
            info.child_tidptr = child_tidptr;
3598
        if (nptl_flags & CLONE_PARENT_SETTID)
3599
            info.parent_tidptr = parent_tidptr;
3600

    
3601
        ret = pthread_attr_init(&attr);
3602
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3603
        /* It is not safe to deliver signals until the child has finished
3604
           initializing, so temporarily block all signals.  */
3605
        sigfillset(&sigmask);
3606
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3607

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

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

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

    
3718
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3719
{
3720
    struct flock fl;
3721
    struct target_flock *target_fl;
3722
    struct flock64 fl64;
3723
    struct target_flock64 *target_fl64;
3724
    abi_long ret;
3725
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3726

    
3727
    if (host_cmd == -TARGET_EINVAL)
3728
            return host_cmd;
3729

    
3730
    switch(cmd) {
3731
    case TARGET_F_GETLK:
3732
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3733
            return -TARGET_EFAULT;
3734
        fl.l_type = tswap16(target_fl->l_type);
3735
        fl.l_whence = tswap16(target_fl->l_whence);
3736
        fl.l_start = tswapl(target_fl->l_start);
3737
        fl.l_len = tswapl(target_fl->l_len);
3738
        fl.l_pid = tswap32(target_fl->l_pid);
3739
        unlock_user_struct(target_fl, arg, 0);
3740
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3741
        if (ret == 0) {
3742
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3743
                return -TARGET_EFAULT;
3744
            target_fl->l_type = tswap16(fl.l_type);
3745
            target_fl->l_whence = tswap16(fl.l_whence);
3746
            target_fl->l_start = tswapl(fl.l_start);
3747
            target_fl->l_len = tswapl(fl.l_len);
3748
            target_fl->l_pid = tswap32(fl.l_pid);
3749
            unlock_user_struct(target_fl, arg, 1);
3750
        }
3751
        break;
3752

    
3753
    case TARGET_F_SETLK:
3754
    case TARGET_F_SETLKW:
3755
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3756
            return -TARGET_EFAULT;
3757
        fl.l_type = tswap16(target_fl->l_type);
3758
        fl.l_whence = tswap16(target_fl->l_whence);
3759
        fl.l_start = tswapl(target_fl->l_start);
3760
        fl.l_len = tswapl(target_fl->l_len);
3761
        fl.l_pid = tswap32(target_fl->l_pid);
3762
        unlock_user_struct(target_fl, arg, 0);
3763
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3764
        break;
3765

    
3766
    case TARGET_F_GETLK64:
3767
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3768
            return -TARGET_EFAULT;
3769
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3770
        fl64.l_whence = tswap16(target_fl64->l_whence);
3771
        fl64.l_start = tswapl(target_fl64->l_start);
3772
        fl64.l_len = tswapl(target_fl64->l_len);
3773
        fl64.l_pid = tswap32(target_fl64->l_pid);
3774
        unlock_user_struct(target_fl64, arg, 0);
3775
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3776
        if (ret == 0) {
3777
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3778
                return -TARGET_EFAULT;
3779
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3780
            target_fl64->l_whence = tswap16(fl64.l_whence);
3781
            target_fl64->l_start = tswapl(fl64.l_start);
3782
            target_fl64->l_len = tswapl(fl64.l_len);
3783
            target_fl64->l_pid = tswap32(fl64.l_pid);
3784
            unlock_user_struct(target_fl64, arg, 1);
3785
        }
3786
        break;
3787
    case TARGET_F_SETLK64:
3788
    case TARGET_F_SETLKW64:
3789
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3790
            return -TARGET_EFAULT;
3791
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3792
        fl64.l_whence = tswap16(target_fl64->l_whence);
3793
        fl64.l_start = tswapl(target_fl64->l_start);
3794
        fl64.l_len = tswapl(target_fl64->l_len);
3795
        fl64.l_pid = tswap32(target_fl64->l_pid);
3796
        unlock_user_struct(target_fl64, arg, 0);
3797
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3798
        break;
3799

    
3800
    case TARGET_F_GETFL:
3801
        ret = get_errno(fcntl(fd, host_cmd, arg));
3802
        if (ret >= 0) {
3803
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3804
        }
3805
        break;
3806

    
3807
    case TARGET_F_SETFL:
3808
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3809
        break;
3810

    
3811
    case TARGET_F_SETOWN:
3812
    case TARGET_F_GETOWN:
3813
    case TARGET_F_SETSIG:
3814
    case TARGET_F_GETSIG:
3815
    case TARGET_F_SETLEASE:
3816
    case TARGET_F_GETLEASE:
3817
        ret = get_errno(fcntl(fd, host_cmd, arg));
3818
        break;
3819

    
3820
    default:
3821
        ret = get_errno(fcntl(fd, cmd, arg));
3822
        break;
3823
    }
3824
    return ret;
3825
}
3826

    
3827
#ifdef USE_UID16
3828

    
3829
static inline int high2lowuid(int uid)
3830
{
3831
    if (uid > 65535)
3832
        return 65534;
3833
    else
3834
        return uid;
3835
}
3836

    
3837
static inline int high2lowgid(int gid)
3838
{
3839
    if (gid > 65535)
3840
        return 65534;
3841
    else
3842
        return gid;
3843
}
3844

    
3845
static inline int low2highuid(int uid)
3846
{
3847
    if ((int16_t)uid == -1)
3848
        return -1;
3849
    else
3850
        return uid;
3851
}
3852

    
3853
static inline int low2highgid(int gid)
3854
{
3855
    if ((int16_t)gid == -1)
3856
        return -1;
3857
    else
3858
        return gid;
3859
}
3860

    
3861
#endif /* USE_UID16 */
3862

    
3863
void syscall_init(void)
3864
{
3865
    IOCTLEntry *ie;
3866
    const argtype *arg_type;
3867
    int size;
3868
    int i;
3869

    
3870
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3871
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3872
#include "syscall_types.h"
3873
#undef STRUCT
3874
#undef STRUCT_SPECIAL
3875

    
3876
    /* we patch the ioctl size if necessary. We rely on the fact that
3877
       no ioctl has all the bits at '1' in the size field */
3878
    ie = ioctl_entries;
3879
    while (ie->target_cmd != 0) {
3880
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3881
            TARGET_IOC_SIZEMASK) {
3882
            arg_type = ie->arg_type;
3883
            if (arg_type[0] != TYPE_PTR) {
3884
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3885
                        ie->target_cmd);
3886
                exit(1);
3887
            }
3888
            arg_type++;
3889
            size = thunk_type_size(arg_type, 0);
3890
            ie->target_cmd = (ie->target_cmd &
3891
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3892
                (size << TARGET_IOC_SIZESHIFT);
3893
        }
3894

    
3895
        /* Build target_to_host_errno_table[] table from
3896
         * host_to_target_errno_table[]. */
3897
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3898
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3899

    
3900
        /* automatic consistency check if same arch */
3901
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3902
    (defined(__x86_64__) && defined(TARGET_X86_64))
3903
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3904
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3905
                    ie->name, ie->target_cmd, ie->host_cmd);
3906
        }
3907
#endif
3908
        ie++;
3909
    }
3910
}
3911

    
3912
#if TARGET_ABI_BITS == 32
3913
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3914
{
3915
#ifdef TARGET_WORDS_BIGENDIAN
3916
    return ((uint64_t)word0 << 32) | word1;
3917
#else
3918
    return ((uint64_t)word1 << 32) | word0;
3919
#endif
3920
}
3921
#else /* TARGET_ABI_BITS == 32 */
3922
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3923
{
3924
    return word0;
3925
}
3926
#endif /* TARGET_ABI_BITS != 32 */
3927

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

    
3945
#ifdef TARGET_NR_ftruncate64
3946
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3947
                                          abi_long arg2,
3948
                                          abi_long arg3,
3949
                                          abi_long arg4)
3950
{
3951
#ifdef TARGET_ARM
3952
    if (((CPUARMState *)cpu_env)->eabi)
3953
      {
3954
        arg2 = arg3;
3955
        arg3 = arg4;
3956
      }
3957
#endif
3958
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3959
}
3960
#endif
3961

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

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

    
3975
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3976
                                               struct timespec *host_ts)
3977
{
3978
    struct target_timespec *target_ts;
3979

    
3980
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3981
        return -TARGET_EFAULT;
3982
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3983
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3984
    unlock_user_struct(target_ts, target_addr, 1);
3985
    return 0;
3986
}
3987

    
3988
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3989
static inline abi_long host_to_target_stat64(void *cpu_env,
3990
                                             abi_ulong target_addr,
3991
                                             struct stat *host_st)
3992
{
3993
#ifdef TARGET_ARM
3994
    if (((CPUARMState *)cpu_env)->eabi) {
3995
        struct target_eabi_stat64 *target_st;
3996

    
3997
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3998
            return -TARGET_EFAULT;
3999
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4000
        __put_user(host_st->st_dev, &target_st->st_dev);
4001
        __put_user(host_st->st_ino, &target_st->st_ino);
4002
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4003
        __put_user(host_st->st_ino, &target_st->__st_ino);
4004
#endif
4005
        __put_user(host_st->st_mode, &target_st->st_mode);
4006
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4007
        __put_user(host_st->st_uid, &target_st->st_uid);
4008
        __put_user(host_st->st_gid, &target_st->st_gid);
4009
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4010
        __put_user(host_st->st_size, &target_st->st_size);
4011
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4012
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4013
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4014
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4015
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4016
        unlock_user_struct(target_st, target_addr, 1);
4017
    } else
4018
#endif
4019
    {
4020
#if (TARGET_LONG_BITS == 64) && (!defined(TARGET_ALPHA))
4021
        struct target_stat *target_st;
4022
#else
4023
        struct target_stat64 *target_st;
4024
#endif
4025

    
4026
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4027
            return -TARGET_EFAULT;
4028
        memset(target_st, 0, sizeof(*target_st));
4029
        __put_user(host_st->st_dev, &target_st->st_dev);
4030
        __put_user(host_st->st_ino, &target_st->st_ino);
4031
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4032
        __put_user(host_st->st_ino, &target_st->__st_ino);
4033
#endif
4034
        __put_user(host_st->st_mode, &target_st->st_mode);
4035
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4036
        __put_user(host_st->st_uid, &target_st->st_uid);
4037
        __put_user(host_st->st_gid, &target_st->st_gid);
4038
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4039
        /* XXX: better use of kernel struct */
4040
        __put_user(host_st->st_size, &target_st->st_size);
4041
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4042
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4043
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4044
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4045
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4046
        unlock_user_struct(target_st, target_addr, 1);
4047
    }
4048

    
4049
    return 0;
4050
}
4051
#endif
4052

    
4053
#if defined(CONFIG_USE_NPTL)
4054
/* ??? Using host futex calls even when target atomic operations
4055
   are not really atomic probably breaks things.  However implementing
4056
   futexes locally would make futexes shared between multiple processes
4057
   tricky.  However they're probably useless because guest atomic
4058
   operations won't work either.  */
4059
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4060
                    target_ulong uaddr2, int val3)
4061
{
4062
    struct timespec ts, *pts;
4063
    int base_op;
4064

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

    
4106
/* Map host to target signal numbers for the wait family of syscalls.
4107
   Assume all other status bits are the same.  */
4108
static int host_to_target_waitstatus(int status)
4109
{
4110
    if (WIFSIGNALED(status)) {
4111
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4112
    }
4113
    if (WIFSTOPPED(status)) {
4114
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4115
               | (status & 0xff);
4116
    }
4117
    return status;
4118
}
4119

    
4120
int get_osversion(void)
4121
{
4122
    static int osversion;
4123
    struct new_utsname buf;
4124
    const char *s;
4125
    int i, n, tmp;
4126
    if (osversion)
4127
        return osversion;
4128
    if (qemu_uname_release && *qemu_uname_release) {
4129
        s = qemu_uname_release;
4130
    } else {
4131
        if (sys_uname(&buf))
4132
            return 0;
4133
        s = buf.release;
4134
    }
4135
    tmp = 0;
4136
    for (i = 0; i < 3; i++) {
4137
        n = 0;
4138
        while (*s >= '0' && *s <= '9') {
4139
            n *= 10;
4140
            n += *s - '0';
4141
            s++;
4142
        }
4143
        tmp = (tmp << 8) + n;
4144
        if (*s == '.')
4145
            s++;
4146
    }
4147
    osversion = tmp;
4148
    return osversion;
4149
}
4150

    
4151
/* do_syscall() should always have a single exit point at the end so
4152
   that actions, such as logging of syscall results, can be performed.
4153
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4154
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4155
                    abi_long arg2, abi_long arg3, abi_long arg4,
4156
                    abi_long arg5, abi_long arg6)
4157
{
4158
    abi_long ret;
4159
    struct stat st;
4160
    struct statfs stfs;
4161
    void *p;
4162

    
4163
#ifdef DEBUG
4164
    gemu_log("syscall %d", num);
4165
#endif
4166
    if(do_strace)
4167
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4168

    
4169
    switch(num) {
4170
    case TARGET_NR_exit:
4171
#ifdef CONFIG_USE_NPTL
4172
      /* In old applications this may be used to implement _exit(2).
4173
         However in threaded applictions it is used for thread termination,
4174
         and _exit_group is used for application termination.
4175
         Do thread termination if we have more then one thread.  */
4176
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4177
         be disabling signals.  */
4178
      if (first_cpu->next_cpu) {
4179
          TaskState *ts;
4180
          CPUState **lastp;
4181
          CPUState *p;
4182

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

    
4346
            argc = 0;
4347
            guest_argp = arg2;
4348
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4349
                if (get_user_ual(addr, gp))
4350
                    goto efault;
4351
                if (!addr)
4352
                    break;
4353
                argc++;
4354
            }
4355
            envc = 0;
4356
            guest_envp = arg3;
4357
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4358
                if (get_user_ual(addr, gp))
4359
                    goto efault;
4360
                if (!addr)
4361
                    break;
4362
                envc++;
4363
            }
4364

    
4365
            argp = alloca((argc + 1) * sizeof(void *));
4366
            envp = alloca((envc + 1) * sizeof(void *));
4367

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

    
4379
            for (gp = guest_envp, q = envp; gp;
4380
                  gp += sizeof(abi_ulong), q++) {
4381
                if (get_user_ual(addr, gp))
4382
                    goto execve_efault;
4383
                if (!addr)
4384
                    break;
4385
                if (!(*q = lock_user_string(addr)))
4386
                    goto execve_efault;
4387
            }
4388
            *q = NULL;
4389

    
4390
            if (!(p = lock_user_string(arg1)))
4391
                goto execve_efault;
4392
            ret = get_errno(execve(p, argp, envp));
4393
            unlock_user(p, arg1, 0);
4394

    
4395
            goto execve_end;
4396

    
4397
        execve_efault:
4398
            ret = -TARGET_EFAULT;
4399

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

    
4815
            if (arg2) {
4816
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4817
                    goto efault;
4818
                act._sa_handler = old_act->_sa_handler;
4819
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4820
                act.sa_flags = old_act->sa_flags;
4821
                unlock_user_struct(old_act, arg2, 0);
4822
                pact = &act;
4823
            } else {
4824
                pact = NULL;
4825
            }
4826

    
4827
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4828

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

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

    
4950
            if (arg2) {
4951
                switch(how) {
4952
                case TARGET_SIG_BLOCK:
4953
                    how = SIG_BLOCK;
4954
                    break;
4955
                case TARGET_SIG_UNBLOCK:
4956
                    how = SIG_UNBLOCK;
4957
                    break;
4958
                case TARGET_SIG_SETMASK:
4959
                    how = SIG_SETMASK;
4960
                    break;
4961
                default:
4962
                    ret = -TARGET_EINVAL;
4963
                    goto fail;
4964
                }
4965
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4966
                    goto efault;
4967
                target_to_host_old_sigset(&set, p);
4968
                unlock_user(p, arg2, 0);
4969
                set_ptr = &set;
4970
            } else {
4971
                how = 0;
4972
                set_ptr = NULL;
4973
            }
4974
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4975
            if (!is_error(ret) && arg3) {
4976
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4977
                    goto efault;
4978
                host_to_target_old_sigset(p, &oldset);
4979
                unlock_user(p, arg3, sizeof(target_sigset_t));
4980
            }
4981
        }
4982
        break;
4983
#endif
4984
    case TARGET_NR_rt_sigprocmask:
4985
        {
4986
            int how = arg1;
4987
            sigset_t set, oldset, *set_ptr;
4988

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

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

    
5142
            ret = get_errno(getrlimit(resource, &rlim));
5143
            if (!is_error(ret)) {
5144
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5145
                    goto efault;
5146
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5147
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
5148
                unlock_user_struct(target_rlim, arg2, 1);
5149
            }
5150
        }
5151
        break;
5152
    case TARGET_NR_getrusage:
5153
        {
5154
            struct rusage rusage;
5155
            ret = get_errno(getrusage(arg1, &rusage));
5156
            if (!is_error(ret)) {
5157
                host_to_target_rusage(arg2, &rusage);
5158
            }
5159
        }
5160
        break;
5161
    case TARGET_NR_gettimeofday:
5162
        {
5163
            struct timeval tv;
5164
            ret = get_errno(gettimeofday(&tv, NULL));
5165
            if (!is_error(ret)) {
5166
                if (copy_to_user_timeval(arg1, &tv))
5167
                    goto efault;
5168
            }
5169
        }
5170
        break;
5171
    case TARGET_NR_settimeofday:
5172
        {
5173
            struct timeval tv;
5174
            if (copy_from_user_timeval(&tv, arg1))
5175
                goto efault;
5176
            ret = get_errno(settimeofday(&tv, NULL));
5177
        }
5178
        break;
5179
#ifdef TARGET_NR_select
5180
    case TARGET_NR_select:
5181
        {
5182
            struct target_sel_arg_struct *sel;
5183
            abi_ulong inp, outp, exp, tvp;
5184
            long nsel;
5185

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

    
5401
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5402
                goto efault;
5403
            __put_user(stfs.f_type, &target_stfs->f_type);
5404
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5405
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5406
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5407
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5408
            __put_user(stfs.f_files, &target_stfs->f_files);
5409
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5410
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5411
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5412
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5413
            unlock_user_struct(target_stfs, arg2, 1);
5414
        }
5415
        break;
5416
    case TARGET_NR_fstatfs:
5417
        ret = get_errno(fstatfs(arg1, &stfs));
5418
        goto convert_statfs;
5419
#ifdef TARGET_NR_statfs64
5420
    case TARGET_NR_statfs64:
5421
        if (!(p = lock_user_string(arg1)))
5422
            goto efault;
5423
        ret = get_errno(statfs(path(p), &stfs));
5424
        unlock_user(p, arg1, 0);
5425
    convert_statfs64:
5426
        if (!is_error(ret)) {
5427
            struct target_statfs64 *target_stfs;
5428

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

    
5543
    case TARGET_NR_syslog:
5544
        if (!(p = lock_user_string(arg2)))
5545
            goto efault;
5546
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5547
        unlock_user(p, arg2, 0);
5548
        break;
5549

    
5550
    case TARGET_NR_setitimer:
5551
        {
5552
            struct itimerval value, ovalue, *pvalue;
5553

    
5554
            if (arg2) {
5555
                pvalue = &value;
5556
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5557
                    || copy_from_user_timeval(&pvalue->it_value,
5558
                                              arg2 + sizeof(struct target_timeval)))
5559
                    goto efault;
5560
            } else {
5561
                pvalue = NULL;
5562
            }
5563
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5564
            if (!is_error(ret) && arg3) {
5565
                if (copy_to_user_timeval(arg3,
5566
                                         &ovalue.it_interval)
5567
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5568
                                            &ovalue.it_value))
5569
                    goto efault;
5570
            }
5571
        }
5572
        break;
5573
    case TARGET_NR_getitimer:
5574
        {
5575
            struct itimerval value;
5576

    
5577
            ret = get_errno(getitimer(arg1, &value));
5578
            if (!is_error(ret) && arg2) {
5579
                if (copy_to_user_timeval(arg2,
5580
                                         &value.it_interval)
5581
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5582
                                            &value.it_value))
5583
                    goto efault;
5584
            }
5585
        }
5586
        break;
5587
    case TARGET_NR_stat:
5588
        if (!(p = lock_user_string(arg1)))
5589
            goto efault;
5590
        ret = get_errno(stat(path(p), &st));
5591
        unlock_user(p, arg1, 0);
5592
        goto do_stat;
5593
    case TARGET_NR_lstat:
5594
        if (!(p = lock_user_string(arg1)))
5595
            goto efault;
5596
        ret = get_errno(lstat(path(p), &st));
5597
        unlock_user(p, arg1, 0);
5598
        goto do_stat;
5599
    case TARGET_NR_fstat:
5600
        {
5601
            ret = get_errno(fstat(arg1, &st));
5602
        do_stat:
5603
            if (!is_error(ret)) {
5604
                struct target_stat *target_st;
5605

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

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

    
5879
            dirp = malloc(count);
5880
            if (!dirp) {
5881
                ret = -TARGET_ENOMEM;
5882
                goto fail;
5883
            }
5884

    
5885
            ret = get_errno(sys_getdents(arg1, dirp, count));
5886
            if (!is_error(ret)) {
5887
                struct linux_dirent *de;
5888
                struct target_dirent *tde;
5889
                int len = ret;
5890
                int reclen, treclen;
5891
                int count1, tnamelen;
5892

    
5893
                count1 = 0;
5894
                de = dirp;
5895
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5896
                    goto efault;
5897
                tde = target_dirp;
5898
                while (len > 0) {
5899
                    reclen = de->d_reclen;
5900
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5901
                    tde->d_reclen = tswap16(treclen);
5902
                    tde->d_ino = tswapl(de->d_ino);
5903
                    tde->d_off = tswapl(de->d_off);
5904
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5905
                    if (tnamelen > 256)
5906
                        tnamelen = 256;
5907
                    /* XXX: may not be correct */
5908
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5909
                    de = (struct linux_dirent *)((char *)de + reclen);
5910
                    len -= reclen;
5911
                    tde = (struct target_dirent *)((char *)tde + treclen);
5912
                    count1 += treclen;
5913
                }
5914
                ret = count1;
5915
                unlock_user(target_dirp, arg2, ret);
5916
            }
5917
            free(dirp);
5918
        }
5919
#else
5920
        {
5921
            struct linux_dirent *dirp;
5922
            abi_long count = arg3;
5923

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

    
5989
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5990
            if (!target_pfd)
5991
                goto efault;
5992
            pfd = alloca(sizeof(struct pollfd) * nfds);
5993
            for(i = 0; i < nfds; i++) {
5994
                pfd[i].fd = tswap32(target_pfd[i].fd);
5995
                pfd[i].events = tswap16(target_pfd[i].events);
5996
            }
5997
            ret = get_errno(poll(pfd, nfds, timeout));
5998
            if (!is_error(ret)) {
5999
                for(i = 0; i < nfds; i++) {
6000
                    target_pfd[i].revents = tswap16(pfd[i].revents);
6001
                }
6002
                ret += nfds * (sizeof(struct target_pollfd)
6003
                               - sizeof(struct pollfd));
6004
            }
6005
            unlock_user(target_pfd, arg1, ret);
6006
        }
6007
        break;
6008
#endif
6009
    case TARGET_NR_flock:
6010
        /* NOTE: the flock constant seems to be the same for every
6011
           Linux platform */
6012
        ret = get_errno(flock(arg1, arg2));
6013
        break;
6014
    case TARGET_NR_readv:
6015
        {
6016
            int count = arg3;
6017
            struct iovec *vec;
6018

    
6019
            vec = alloca(count * sizeof(struct iovec));
6020
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6021
                goto efault;
6022
            ret = get_errno(readv(arg1, vec, count));
6023
            unlock_iovec(vec, arg2, count, 1);
6024
        }
6025
        break;
6026
    case TARGET_NR_writev:
6027
        {
6028
            int count = arg3;
6029
            struct iovec *vec;
6030

    
6031
            vec = alloca(count * sizeof(struct iovec));
6032
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6033
                goto efault;
6034
            ret = get_errno(writev(arg1, vec, count));
6035
            unlock_iovec(vec, arg2, count, 0);
6036
        }
6037
        break;
6038
    case TARGET_NR_getsid:
6039
        ret = get_errno(getsid(arg1));
6040
        break;
6041
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6042
    case TARGET_NR_fdatasync:
6043
        ret = get_errno(fdatasync(arg1));
6044
        break;
6045
#endif
6046
    case TARGET_NR__sysctl:
6047
        /* We don't implement this, but ENOTDIR is always a safe
6048
           return value. */
6049
        ret = -TARGET_ENOTDIR;
6050
        break;
6051
    case TARGET_NR_sched_setparam:
6052
        {
6053
            struct sched_param *target_schp;
6054
            struct sched_param schp;
6055

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

    
6330
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6331
            ret = get_errno(getgroups(gidsetsize, grouplist));
6332
            if (gidsetsize == 0)
6333
                break;
6334
            if (!is_error(ret)) {
6335
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6336
                if (!target_grouplist)
6337
                    goto efault;
6338
                for(i = 0;i < ret; i++)
6339
                    target_grouplist[i] = tswap16(grouplist[i]);
6340
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6341
            }
6342
        }
6343
        break;
6344
    case TARGET_NR_setgroups:
6345
        {
6346
            int gidsetsize = arg1;
6347
            uint16_t *target_grouplist;
6348
            gid_t *grouplist;
6349
            int i;
6350

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

    
6436
#ifdef TARGET_NR_lchown32
6437
    case TARGET_NR_lchown32:
6438
        if (!(p = lock_user_string(arg1)))
6439
            goto efault;
6440
        ret = get_errno(lchown(p, arg2, arg3));
6441
        unlock_user(p, arg1, 0);
6442
        break;
6443
#endif
6444
#ifdef TARGET_NR_getuid32
6445
    case TARGET_NR_getuid32:
6446
        ret = get_errno(getuid());
6447
        break;
6448
#endif
6449

    
6450
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6451
   /* Alpha specific */
6452
    case TARGET_NR_getxuid:
6453
         {
6454
            uid_t euid;
6455
            euid=geteuid();
6456
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6457
         }
6458
        ret = get_errno(getuid());
6459
        break;
6460
#endif
6461
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6462
   /* Alpha specific */
6463
    case TARGET_NR_getxgid:
6464
         {
6465
            uid_t egid;
6466
            egid=getegid();
6467
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6468
         }
6469
        ret = get_errno(getgid());
6470
        break;
6471
#endif
6472
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
6473
    /* Alpha specific */
6474
    case TARGET_NR_osf_getsysinfo:
6475
        ret = -TARGET_EOPNOTSUPP;
6476
        switch (arg1) {
6477
          case TARGET_GSI_IEEE_FP_CONTROL:
6478
            {
6479
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
6480

    
6481
                /* Copied from linux ieee_fpcr_to_swcr.  */
6482
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
6483
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
6484
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
6485
                                        | SWCR_TRAP_ENABLE_DZE
6486
                                        | SWCR_TRAP_ENABLE_OVF);
6487
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
6488
                                        | SWCR_TRAP_ENABLE_INE);
6489
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
6490
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
6491

    
6492
                if (put_user_u64 (swcr, arg2))
6493
                        goto efault;
6494
                ret = 0;
6495
            }
6496
            break;
6497

    
6498
          /* case GSI_IEEE_STATE_AT_SIGNAL:
6499
             -- Not implemented in linux kernel.
6500
             case GSI_UACPROC:
6501
             -- Retrieves current unaligned access state; not much used.
6502
             case GSI_PROC_TYPE:
6503
             -- Retrieves implver information; surely not used.
6504
             case GSI_GET_HWRPB:
6505
             -- Grabs a copy of the HWRPB; surely not used.
6506
          */
6507
        }
6508
        break;
6509
#endif
6510
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
6511
    /* Alpha specific */
6512
    case TARGET_NR_osf_setsysinfo:
6513
        ret = -TARGET_EOPNOTSUPP;
6514
        switch (arg1) {
6515
          case TARGET_SSI_IEEE_FP_CONTROL:
6516
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
6517
            {
6518
                uint64_t swcr, fpcr, orig_fpcr;
6519

    
6520
                if (get_user_u64 (swcr, arg2))
6521
                    goto efault;
6522
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6523
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6524

    
6525
                /* Copied from linux ieee_swcr_to_fpcr.  */
6526
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
6527
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
6528
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
6529
                                  | SWCR_TRAP_ENABLE_DZE
6530
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
6531
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
6532
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
6533
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
6534
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
6535

    
6536
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6537
                ret = 0;
6538

    
6539
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6540
                    /* Old exceptions are not signaled.  */
6541
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6542

    
6543
                    /* If any exceptions set by this call, and are unmasked,
6544
                       send a signal.  */
6545
                    /* ??? FIXME */
6546
                }
6547
            }
6548
            break;
6549

    
6550
          /* case SSI_NVPAIRS:
6551
             -- Used with SSIN_UACPROC to enable unaligned accesses.
6552
             case SSI_IEEE_STATE_AT_SIGNAL:
6553
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
6554
             -- Not implemented in linux kernel
6555
          */
6556
        }
6557
        break;
6558
#endif
6559
#ifdef TARGET_NR_osf_sigprocmask
6560
    /* Alpha specific.  */
6561
    case TARGET_NR_osf_sigprocmask:
6562
        {
6563
            abi_ulong mask;
6564
            int how = arg1;
6565
            sigset_t set, oldset;
6566

    
6567
            switch(arg1) {
6568
            case TARGET_SIG_BLOCK:
6569
                how = SIG_BLOCK;
6570
                break;
6571
            case TARGET_SIG_UNBLOCK:
6572
                how = SIG_UNBLOCK;
6573
                break;
6574
            case TARGET_SIG_SETMASK:
6575
                how = SIG_SETMASK;
6576
                break;
6577
            default:
6578
                ret = -TARGET_EINVAL;
6579
                goto fail;
6580
            }
6581
            mask = arg2;
6582
            target_to_host_old_sigset(&set, &mask);
6583
            sigprocmask(arg1, &set, &oldset);
6584
            host_to_target_old_sigset(&mask, &oldset);
6585
            ret = mask;
6586
        }
6587
        break;
6588
#endif
6589

    
6590
#ifdef TARGET_NR_getgid32
6591
    case TARGET_NR_getgid32:
6592
        ret = get_errno(getgid());
6593
        break;
6594
#endif
6595
#ifdef TARGET_NR_geteuid32
6596
    case TARGET_NR_geteuid32:
6597
        ret = get_errno(geteuid());
6598
        break;
6599
#endif
6600
#ifdef TARGET_NR_getegid32
6601
    case TARGET_NR_getegid32:
6602
        ret = get_errno(getegid());
6603
        break;
6604
#endif
6605
#ifdef TARGET_NR_setreuid32
6606
    case TARGET_NR_setreuid32:
6607
        ret = get_errno(setreuid(arg1, arg2));
6608
        break;
6609
#endif
6610
#ifdef TARGET_NR_setregid32
6611
    case TARGET_NR_setregid32:
6612
        ret = get_errno(setregid(arg1, arg2));
6613
        break;
6614
#endif
6615
#ifdef TARGET_NR_getgroups32
6616
    case TARGET_NR_getgroups32:
6617
        {
6618
            int gidsetsize = arg1;
6619
            uint32_t *target_grouplist;
6620
            gid_t *grouplist;
6621
            int i;
6622

    
6623
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6624
            ret = get_errno(getgroups(gidsetsize, grouplist));
6625
            if (gidsetsize == 0)
6626
                break;
6627
            if (!is_error(ret)) {
6628
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6629
                if (!target_grouplist) {
6630
                    ret = -TARGET_EFAULT;
6631
                    goto fail;
6632
                }
6633
                for(i = 0;i < ret; i++)
6634
                    target_grouplist[i] = tswap32(grouplist[i]);
6635
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6636
            }
6637
        }
6638
        break;
6639
#endif
6640
#ifdef TARGET_NR_setgroups32
6641
    case TARGET_NR_setgroups32:
6642
        {
6643
            int gidsetsize = arg1;
6644
            uint32_t *target_grouplist;
6645
            gid_t *grouplist;
6646
            int i;
6647

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

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

    
6802
        cmd = target_to_host_fcntl_cmd(arg2);
6803
        if (cmd == -TARGET_EINVAL)
6804
                return cmd;
6805

    
6806
        switch(arg2) {
6807
        case TARGET_F_GETLK64:
6808
#ifdef TARGET_ARM
6809
            if (((CPUARMState *)cpu_env)->eabi) {
6810
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6811
                    goto efault;
6812
                fl.l_type = tswap16(target_efl->l_type);
6813
                fl.l_whence = tswap16(target_efl->l_whence);
6814
                fl.l_start = tswap64(target_efl->l_start);
6815
                fl.l_len = tswap64(target_efl->l_len);
6816
                fl.l_pid = tswap32(target_efl->l_pid);
6817
                unlock_user_struct(target_efl, arg3, 0);
6818
            } else
6819
#endif
6820
            {
6821
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6822
                    goto efault;
6823
                fl.l_type = tswap16(target_fl->l_type);
6824
                fl.l_whence = tswap16(target_fl->l_whence);
6825
                fl.l_start = tswap64(target_fl->l_start);
6826
                fl.l_len = tswap64(target_fl->l_len);
6827
                fl.l_pid = tswap32(target_fl->l_pid);
6828
                unlock_user_struct(target_fl, arg3, 0);
6829
            }
6830
            ret = get_errno(fcntl(arg1, cmd, &fl));
6831
            if (ret == 0) {
6832
#ifdef TARGET_ARM
6833
                if (((CPUARMState *)cpu_env)->eabi) {
6834
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6835
                        goto efault;
6836
                    target_efl->l_type = tswap16(fl.l_type);
6837
                    target_efl->l_whence = tswap16(fl.l_whence);
6838
                    target_efl->l_start = tswap64(fl.l_start);
6839
                    target_efl->l_len = tswap64(fl.l_len);
6840
                    target_efl->l_pid = tswap32(fl.l_pid);
6841
                    unlock_user_struct(target_efl, arg3, 1);
6842
                } else
6843
#endif
6844
                {
6845
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6846
                        goto efault;
6847
                    target_fl->l_type = tswap16(fl.l_type);
6848
                    target_fl->l_whence = tswap16(fl.l_whence);
6849
                    target_fl->l_start = tswap64(fl.l_start);
6850
                    target_fl->l_len = tswap64(fl.l_len);
6851
                    target_fl->l_pid = tswap32(fl.l_pid);
6852
                    unlock_user_struct(target_fl, arg3, 1);
6853
                }
6854
            }
6855
            break;
6856

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

    
6975
#ifdef TARGET_NR_clock_gettime
6976
    case TARGET_NR_clock_gettime:
6977
    {
6978
        struct timespec ts;
6979
        ret = get_errno(clock_gettime(arg1, &ts));
6980
        if (!is_error(ret)) {
6981
            host_to_target_timespec(arg2, &ts);
6982
        }
6983
        break;
6984
    }
6985
#endif
6986
#ifdef TARGET_NR_clock_getres
6987
    case TARGET_NR_clock_getres:
6988
    {
6989
        struct timespec ts;
6990
        ret = get_errno(clock_getres(arg1, &ts));
6991
        if (!is_error(ret)) {
6992
            host_to_target_timespec(arg2, &ts);
6993
        }
6994
        break;
6995
    }
6996
#endif
6997
#ifdef TARGET_NR_clock_nanosleep
6998
    case TARGET_NR_clock_nanosleep:
6999
    {
7000
        struct timespec ts;
7001
        target_to_host_timespec(&ts, arg3);
7002
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
7003
        if (arg4)
7004
            host_to_target_timespec(arg4, &ts);
7005
        break;
7006
    }
7007
#endif
7008

    
7009
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7010
    case TARGET_NR_set_tid_address:
7011
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7012
        break;
7013
#endif
7014

    
7015
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7016
    case TARGET_NR_tkill:
7017
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7018
        break;
7019
#endif
7020

    
7021
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7022
    case TARGET_NR_tgkill:
7023
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7024
                        target_to_host_signal(arg3)));
7025
        break;
7026
#endif
7027

    
7028
#ifdef TARGET_NR_set_robust_list
7029
    case TARGET_NR_set_robust_list:
7030
        goto unimplemented_nowarn;
7031
#endif
7032

    
7033
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7034
    case TARGET_NR_utimensat:
7035
        {
7036
            struct timespec *tsp, ts[2];
7037
            if (!arg3) {
7038
                tsp = NULL;
7039
            } else {
7040
                target_to_host_timespec(ts, arg3);
7041
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7042
                tsp = ts;
7043
            }
7044
            if (!arg2)
7045
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7046
            else {
7047
                if (!(p = lock_user_string(arg2))) {
7048
                    ret = -TARGET_EFAULT;
7049
                    goto fail;
7050
                }
7051
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7052
                unlock_user(p, arg2, 0);
7053
            }
7054
        }
7055
        break;
7056
#endif
7057
#if defined(CONFIG_USE_NPTL)
7058
    case TARGET_NR_futex:
7059
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7060
        break;
7061
#endif
7062
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7063
    case TARGET_NR_inotify_init:
7064
        ret = get_errno(sys_inotify_init());
7065
        break;
7066
#endif
7067
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
7068
    case TARGET_NR_inotify_init1:
7069
        ret = get_errno(sys_inotify_init1(arg1));
7070
        break;
7071
#endif
7072
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7073
    case TARGET_NR_inotify_add_watch:
7074
        p = lock_user_string(arg2);
7075
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7076
        unlock_user(p, arg2, 0);
7077
        break;
7078
#endif
7079
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7080
    case TARGET_NR_inotify_rm_watch:
7081
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7082
        break;
7083
#endif
7084

    
7085
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7086
    case TARGET_NR_mq_open:
7087
        {
7088
            struct mq_attr posix_mq_attr;
7089

    
7090
            p = lock_user_string(arg1 - 1);
7091
            if (arg4 != 0)
7092
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7093
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7094
            unlock_user (p, arg1, 0);
7095
        }
7096
        break;
7097

    
7098
    case TARGET_NR_mq_unlink:
7099
        p = lock_user_string(arg1 - 1);
7100
        ret = get_errno(mq_unlink(p));
7101
        unlock_user (p, arg1, 0);
7102
        break;
7103

    
7104
    case TARGET_NR_mq_timedsend:
7105
        {
7106
            struct timespec ts;
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_timedsend(arg1, p, arg3, arg4, &ts));
7112
                host_to_target_timespec(arg5, &ts);
7113
            }
7114
            else
7115
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7116
            unlock_user (p, arg2, arg3);
7117
        }
7118
        break;
7119

    
7120
    case TARGET_NR_mq_timedreceive:
7121
        {
7122
            struct timespec ts;
7123
            unsigned int prio;
7124

    
7125
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7126
            if (arg5 != 0) {
7127
                target_to_host_timespec(&ts, arg5);
7128
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7129
                host_to_target_timespec(arg5, &ts);
7130
            }
7131
            else
7132
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7133
            unlock_user (p, arg2, arg3);
7134
            if (arg4 != 0)
7135
                put_user_u32(prio, arg4);
7136
        }
7137
        break;
7138

    
7139
    /* Not implemented for now... */
7140
/*     case TARGET_NR_mq_notify: */
7141
/*         break; */
7142

    
7143
    case TARGET_NR_mq_getsetattr:
7144
        {
7145
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7146
            ret = 0;
7147
            if (arg3 != 0) {
7148
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7149
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7150
            }
7151
            if (arg2 != 0) {
7152
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7153
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7154
            }
7155

    
7156
        }
7157
        break;
7158
#endif
7159

    
7160
#ifdef CONFIG_SPLICE
7161
#ifdef TARGET_NR_tee
7162
    case TARGET_NR_tee:
7163
        {
7164
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7165
        }
7166
        break;
7167
#endif
7168
#ifdef TARGET_NR_splice
7169
    case TARGET_NR_splice:
7170
        {
7171
            loff_t loff_in, loff_out;
7172
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7173
            if(arg2) {
7174
                get_user_u64(loff_in, arg2);
7175
                ploff_in = &loff_in;
7176
            }
7177
            if(arg4) {
7178
                get_user_u64(loff_out, arg2);
7179
                ploff_out = &loff_out;
7180
            }
7181
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7182
        }
7183
        break;
7184
#endif
7185
#ifdef TARGET_NR_vmsplice
7186
        case TARGET_NR_vmsplice:
7187
        {
7188
            int count = arg3;
7189
            struct iovec *vec;
7190

    
7191
            vec = alloca(count * sizeof(struct iovec));
7192
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7193
                goto efault;
7194
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7195
            unlock_iovec(vec, arg2, count, 0);
7196
        }
7197
        break;
7198
#endif
7199
#endif /* CONFIG_SPLICE */
7200
#ifdef CONFIG_EVENTFD
7201
#if defined(TARGET_NR_eventfd)
7202
    case TARGET_NR_eventfd:
7203
        ret = get_errno(eventfd(arg1, 0));
7204
        break;
7205
#endif
7206
#if defined(TARGET_NR_eventfd2)
7207
    case TARGET_NR_eventfd2:
7208
        ret = get_errno(eventfd(arg1, arg2));
7209
        break;
7210
#endif
7211
#endif /* CONFIG_EVENTFD  */
7212
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7213
    case TARGET_NR_fallocate:
7214
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7215
        break;
7216
#endif
7217
    default:
7218
    unimplemented:
7219
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7220
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7221
    unimplemented_nowarn:
7222
#endif
7223
        ret = -TARGET_ENOSYS;
7224
        break;
7225
    }
7226
fail:
7227
#ifdef DEBUG
7228
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7229
#endif
7230
    if(do_strace)
7231
        print_syscall_ret(num, ret);
7232
    return ret;
7233
efault:
7234
    ret = -TARGET_EFAULT;
7235
    goto fail;
7236
}