Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 3b3f24ad

History | View | Annotate | Download (199.8 kB)

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

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

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

    
82
#include "qemu.h"
83
#include "qemu-common.h"
84

    
85
#if defined(USE_NPTL)
86
#include <linux/futex.h>
87
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
88
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
89
#else
90
/* XXX: Hardcode the above values.  */
91
#define CLONE_NPTL_FLAGS2 0
92
#endif
93

    
94
//#define DEBUG
95

    
96
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
97
    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
98
/* 16 bit uid wrappers emulation */
99
#define USE_UID16
100
#endif
101

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

    
106

    
107
#undef _syscall0
108
#undef _syscall1
109
#undef _syscall2
110
#undef _syscall3
111
#undef _syscall4
112
#undef _syscall5
113
#undef _syscall6
114

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

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

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

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

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

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

    
152

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

    
161

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

    
191
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
192
#define __NR__llseek __NR_lseek
193
#endif
194

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

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

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

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

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

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

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

    
287
#undef COPY_UTSNAME_FIELD
288
}
289

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

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

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

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

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

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

    
486
#endif /* CONFIG_ATFILE */
487

    
488
#ifdef CONFIG_INOTIFY
489

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

    
515

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

    
522
#define ERRNO_TABLE_SIZE 1200
523

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

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

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

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

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

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

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

    
673
static abi_ulong target_brk;
674
static abi_ulong target_original_brk;
675

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

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

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

    
693
    brk_page = HOST_PAGE_ALIGN(target_brk);
694

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

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

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

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

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

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

    
740
    unlock_user(target_fds, target_fds_addr, 0);
741

    
742
    return 0;
743
}
744

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

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

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

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

    
772
    return 0;
773
}
774

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

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

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

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

    
817
    return 0;
818
}
819

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

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

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

    
831
    unlock_user_struct(target_tv, target_tv_addr, 0);
832

    
833
    return 0;
834
}
835

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

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

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

    
847
    unlock_user_struct(target_tv, target_tv_addr, 1);
848

    
849
    return 0;
850
}
851

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

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

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

    
866
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
867

    
868
    return 0;
869
}
870

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

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

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

    
885
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
886

    
887
    return 0;
888
}
889

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

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

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

    
930
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
931

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

    
940
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
941
            return -TARGET_EFAULT;
942
    }
943

    
944
    return ret;
945
}
946

    
947
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
948
                                               abi_ulong target_addr,
949
                                               socklen_t len)
950
{
951
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
952
    sa_family_t sa_family;
953
    struct target_sockaddr *target_saddr;
954

    
955
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
956
    if (!target_saddr)
957
        return -TARGET_EFAULT;
958

    
959
    sa_family = tswap16(target_saddr->sa_family);
960

    
961
    /* Oops. The caller might send a incomplete sun_path; sun_path
962
     * must be terminated by \0 (see the manual page), but
963
     * unfortunately it is quite common to specify sockaddr_un
964
     * length as "strlen(x->sun_path)" while it should be
965
     * "strlen(...) + 1". We'll fix that here if needed.
966
     * Linux kernel has a similar feature.
967
     */
968

    
969
    if (sa_family == AF_UNIX) {
970
        if (len < unix_maxlen && len > 0) {
971
            char *cp = (char*)target_saddr;
972

    
973
            if ( cp[len-1] && !cp[len] )
974
                len++;
975
        }
976
        if (len > unix_maxlen)
977
            len = unix_maxlen;
978
    }
979

    
980
    memcpy(addr, target_saddr, len);
981
    addr->sa_family = sa_family;
982
    unlock_user(target_saddr, target_addr, 0);
983

    
984
    return 0;
985
}
986

    
987
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
988
                                               struct sockaddr *addr,
989
                                               socklen_t len)
990
{
991
    struct target_sockaddr *target_saddr;
992

    
993
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
994
    if (!target_saddr)
995
        return -TARGET_EFAULT;
996
    memcpy(target_saddr, addr, len);
997
    target_saddr->sa_family = tswap16(addr->sa_family);
998
    unlock_user(target_saddr, target_addr, len);
999

    
1000
    return 0;
1001
}
1002

    
1003
/* ??? Should this also swap msgh->name?  */
1004
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1005
                                           struct target_msghdr *target_msgh)
1006
{
1007
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1008
    abi_long msg_controllen;
1009
    abi_ulong target_cmsg_addr;
1010
    struct target_cmsghdr *target_cmsg;
1011
    socklen_t space = 0;
1012
    
1013
    msg_controllen = tswapl(target_msgh->msg_controllen);
1014
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1015
        goto the_end;
1016
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1017
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1018
    if (!target_cmsg)
1019
        return -TARGET_EFAULT;
1020

    
1021
    while (cmsg && target_cmsg) {
1022
        void *data = CMSG_DATA(cmsg);
1023
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1024

    
1025
        int len = tswapl(target_cmsg->cmsg_len)
1026
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1027

    
1028
        space += CMSG_SPACE(len);
1029
        if (space > msgh->msg_controllen) {
1030
            space -= CMSG_SPACE(len);
1031
            gemu_log("Host cmsg overflow\n");
1032
            break;
1033
        }
1034

    
1035
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1036
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1037
        cmsg->cmsg_len = CMSG_LEN(len);
1038

    
1039
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1040
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1041
            memcpy(data, target_data, len);
1042
        } else {
1043
            int *fd = (int *)data;
1044
            int *target_fd = (int *)target_data;
1045
            int i, numfds = len / sizeof(int);
1046

    
1047
            for (i = 0; i < numfds; i++)
1048
                fd[i] = tswap32(target_fd[i]);
1049
        }
1050

    
1051
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1052
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1053
    }
1054
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1055
 the_end:
1056
    msgh->msg_controllen = space;
1057
    return 0;
1058
}
1059

    
1060
/* ??? Should this also swap msgh->name?  */
1061
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1062
                                           struct msghdr *msgh)
1063
{
1064
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1065
    abi_long msg_controllen;
1066
    abi_ulong target_cmsg_addr;
1067
    struct target_cmsghdr *target_cmsg;
1068
    socklen_t space = 0;
1069

    
1070
    msg_controllen = tswapl(target_msgh->msg_controllen);
1071
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1072
        goto the_end;
1073
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1074
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1075
    if (!target_cmsg)
1076
        return -TARGET_EFAULT;
1077

    
1078
    while (cmsg && target_cmsg) {
1079
        void *data = CMSG_DATA(cmsg);
1080
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1081

    
1082
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1083

    
1084
        space += TARGET_CMSG_SPACE(len);
1085
        if (space > msg_controllen) {
1086
            space -= TARGET_CMSG_SPACE(len);
1087
            gemu_log("Target cmsg overflow\n");
1088
            break;
1089
        }
1090

    
1091
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1092
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1093
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1094

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

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

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

    
1116
/* do_setsockopt() Must return target values and target errnos. */
1117
static abi_long do_setsockopt(int sockfd, int level, int optname,
1118
                              abi_ulong optval_addr, socklen_t optlen)
1119
{
1120
    abi_long ret;
1121
    int val;
1122

    
1123
    switch(level) {
1124
    case SOL_TCP:
1125
        /* TCP options all take an 'int' value.  */
1126
        if (optlen < sizeof(uint32_t))
1127
            return -TARGET_EINVAL;
1128

    
1129
        if (get_user_u32(val, optval_addr))
1130
            return -TARGET_EFAULT;
1131
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1132
        break;
1133
    case SOL_IP:
1134
        switch(optname) {
1135
        case IP_TOS:
1136
        case IP_TTL:
1137
        case IP_HDRINCL:
1138
        case IP_ROUTER_ALERT:
1139
        case IP_RECVOPTS:
1140
        case IP_RETOPTS:
1141
        case IP_PKTINFO:
1142
        case IP_MTU_DISCOVER:
1143
        case IP_RECVERR:
1144
        case IP_RECVTOS:
1145
#ifdef IP_FREEBIND
1146
        case IP_FREEBIND:
1147
#endif
1148
        case IP_MULTICAST_TTL:
1149
        case IP_MULTICAST_LOOP:
1150
            val = 0;
1151
            if (optlen >= sizeof(uint32_t)) {
1152
                if (get_user_u32(val, optval_addr))
1153
                    return -TARGET_EFAULT;
1154
            } else if (optlen >= 1) {
1155
                if (get_user_u8(val, optval_addr))
1156
                    return -TARGET_EFAULT;
1157
            }
1158
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1159
            break;
1160
        default:
1161
            goto unimplemented;
1162
        }
1163
        break;
1164
    case TARGET_SOL_SOCKET:
1165
        switch (optname) {
1166
            /* Options with 'int' argument.  */
1167
        case TARGET_SO_DEBUG:
1168
                optname = SO_DEBUG;
1169
                break;
1170
        case TARGET_SO_REUSEADDR:
1171
                optname = SO_REUSEADDR;
1172
                break;
1173
        case TARGET_SO_TYPE:
1174
                optname = SO_TYPE;
1175
                break;
1176
        case TARGET_SO_ERROR:
1177
                optname = SO_ERROR;
1178
                break;
1179
        case TARGET_SO_DONTROUTE:
1180
                optname = SO_DONTROUTE;
1181
                break;
1182
        case TARGET_SO_BROADCAST:
1183
                optname = SO_BROADCAST;
1184
                break;
1185
        case TARGET_SO_SNDBUF:
1186
                optname = SO_SNDBUF;
1187
                break;
1188
        case TARGET_SO_RCVBUF:
1189
                optname = SO_RCVBUF;
1190
                break;
1191
        case TARGET_SO_KEEPALIVE:
1192
                optname = SO_KEEPALIVE;
1193
                break;
1194
        case TARGET_SO_OOBINLINE:
1195
                optname = SO_OOBINLINE;
1196
                break;
1197
        case TARGET_SO_NO_CHECK:
1198
                optname = SO_NO_CHECK;
1199
                break;
1200
        case TARGET_SO_PRIORITY:
1201
                optname = SO_PRIORITY;
1202
                break;
1203
#ifdef SO_BSDCOMPAT
1204
        case TARGET_SO_BSDCOMPAT:
1205
                optname = SO_BSDCOMPAT;
1206
                break;
1207
#endif
1208
        case TARGET_SO_PASSCRED:
1209
                optname = SO_PASSCRED;
1210
                break;
1211
        case TARGET_SO_TIMESTAMP:
1212
                optname = SO_TIMESTAMP;
1213
                break;
1214
        case TARGET_SO_RCVLOWAT:
1215
                optname = SO_RCVLOWAT;
1216
                break;
1217
        case TARGET_SO_RCVTIMEO:
1218
                optname = SO_RCVTIMEO;
1219
                break;
1220
        case TARGET_SO_SNDTIMEO:
1221
                optname = SO_SNDTIMEO;
1222
                break;
1223
            break;
1224
        default:
1225
            goto unimplemented;
1226
        }
1227
        if (optlen < sizeof(uint32_t))
1228
            return -TARGET_EINVAL;
1229

    
1230
        if (get_user_u32(val, optval_addr))
1231
            return -TARGET_EFAULT;
1232
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1233
        break;
1234
    default:
1235
    unimplemented:
1236
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1237
        ret = -TARGET_ENOPROTOOPT;
1238
    }
1239
    return ret;
1240
}
1241

    
1242
/* do_getsockopt() Must return target values and target errnos. */
1243
static abi_long do_getsockopt(int sockfd, int level, int optname,
1244
                              abi_ulong optval_addr, abi_ulong optlen)
1245
{
1246
    abi_long ret;
1247
    int len, val;
1248
    socklen_t lv;
1249

    
1250
    switch(level) {
1251
    case TARGET_SOL_SOCKET:
1252
            level = SOL_SOCKET;
1253
        switch (optname) {
1254
        case TARGET_SO_LINGER:
1255
        case TARGET_SO_RCVTIMEO:
1256
        case TARGET_SO_SNDTIMEO:
1257
        case TARGET_SO_PEERCRED:
1258
        case TARGET_SO_PEERNAME:
1259
            /* These don't just return a single integer */
1260
            goto unimplemented;
1261
        default:
1262
            goto int_case;
1263
        }
1264
        break;
1265
    case SOL_TCP:
1266
        /* TCP options all take an 'int' value.  */
1267
    int_case:
1268
        if (get_user_u32(len, optlen))
1269
            return -TARGET_EFAULT;
1270
        if (len < 0)
1271
            return -TARGET_EINVAL;
1272
        lv = sizeof(int);
1273
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1274
        if (ret < 0)
1275
            return ret;
1276
        val = tswap32(val);
1277
        if (len > lv)
1278
            len = lv;
1279
        if (len == 4) {
1280
            if (put_user_u32(val, optval_addr))
1281
                return -TARGET_EFAULT;
1282
        } else {
1283
            if (put_user_u8(val, optval_addr))
1284
                return -TARGET_EFAULT;
1285
        }
1286
        if (put_user_u32(len, optlen))
1287
            return -TARGET_EFAULT;
1288
        break;
1289
    case SOL_IP:
1290
        switch(optname) {
1291
        case IP_TOS:
1292
        case IP_TTL:
1293
        case IP_HDRINCL:
1294
        case IP_ROUTER_ALERT:
1295
        case IP_RECVOPTS:
1296
        case IP_RETOPTS:
1297
        case IP_PKTINFO:
1298
        case IP_MTU_DISCOVER:
1299
        case IP_RECVERR:
1300
        case IP_RECVTOS:
1301
#ifdef IP_FREEBIND
1302
        case IP_FREEBIND:
1303
#endif
1304
        case IP_MULTICAST_TTL:
1305
        case IP_MULTICAST_LOOP:
1306
            if (get_user_u32(len, optlen))
1307
                return -TARGET_EFAULT;
1308
            if (len < 0)
1309
                return -TARGET_EINVAL;
1310
            lv = sizeof(int);
1311
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1312
            if (ret < 0)
1313
                return ret;
1314
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1315
                len = 1;
1316
                if (put_user_u32(len, optlen)
1317
                    || put_user_u8(val, optval_addr))
1318
                    return -TARGET_EFAULT;
1319
            } else {
1320
                if (len > sizeof(int))
1321
                    len = sizeof(int);
1322
                if (put_user_u32(len, optlen)
1323
                    || put_user_u32(val, optval_addr))
1324
                    return -TARGET_EFAULT;
1325
            }
1326
            break;
1327
        default:
1328
            ret = -TARGET_ENOPROTOOPT;
1329
            break;
1330
        }
1331
        break;
1332
    default:
1333
    unimplemented:
1334
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1335
                 level, optname);
1336
        ret = -TARGET_EOPNOTSUPP;
1337
        break;
1338
    }
1339
    return ret;
1340
}
1341

    
1342
/* FIXME
1343
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1344
 * other lock functions have a return code of 0 for failure.
1345
 */
1346
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1347
                           int count, int copy)
1348
{
1349
    struct target_iovec *target_vec;
1350
    abi_ulong base;
1351
    int i;
1352

    
1353
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1354
    if (!target_vec)
1355
        return -TARGET_EFAULT;
1356
    for(i = 0;i < count; i++) {
1357
        base = tswapl(target_vec[i].iov_base);
1358
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1359
        if (vec[i].iov_len != 0) {
1360
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1361
            /* Don't check lock_user return value. We must call writev even
1362
               if a element has invalid base address. */
1363
        } else {
1364
            /* zero length pointer is ignored */
1365
            vec[i].iov_base = NULL;
1366
        }
1367
    }
1368
    unlock_user (target_vec, target_addr, 0);
1369
    return 0;
1370
}
1371

    
1372
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1373
                             int count, int copy)
1374
{
1375
    struct target_iovec *target_vec;
1376
    abi_ulong base;
1377
    int i;
1378

    
1379
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1380
    if (!target_vec)
1381
        return -TARGET_EFAULT;
1382
    for(i = 0;i < count; i++) {
1383
        if (target_vec[i].iov_base) {
1384
            base = tswapl(target_vec[i].iov_base);
1385
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1386
        }
1387
    }
1388
    unlock_user (target_vec, target_addr, 0);
1389

    
1390
    return 0;
1391
}
1392

    
1393
/* do_socket() Must return target values and target errnos. */
1394
static abi_long do_socket(int domain, int type, int protocol)
1395
{
1396
#if defined(TARGET_MIPS)
1397
    switch(type) {
1398
    case TARGET_SOCK_DGRAM:
1399
        type = SOCK_DGRAM;
1400
        break;
1401
    case TARGET_SOCK_STREAM:
1402
        type = SOCK_STREAM;
1403
        break;
1404
    case TARGET_SOCK_RAW:
1405
        type = SOCK_RAW;
1406
        break;
1407
    case TARGET_SOCK_RDM:
1408
        type = SOCK_RDM;
1409
        break;
1410
    case TARGET_SOCK_SEQPACKET:
1411
        type = SOCK_SEQPACKET;
1412
        break;
1413
    case TARGET_SOCK_PACKET:
1414
        type = SOCK_PACKET;
1415
        break;
1416
    }
1417
#endif
1418
    if (domain == PF_NETLINK)
1419
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1420
    return get_errno(socket(domain, type, protocol));
1421
}
1422

    
1423
/* do_bind() Must return target values and target errnos. */
1424
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1425
                        socklen_t addrlen)
1426
{
1427
    void *addr;
1428

    
1429
    if (addrlen < 0)
1430
        return -TARGET_EINVAL;
1431

    
1432
    addr = alloca(addrlen+1);
1433

    
1434
    target_to_host_sockaddr(addr, target_addr, addrlen);
1435
    return get_errno(bind(sockfd, addr, addrlen));
1436
}
1437

    
1438
/* do_connect() Must return target values and target errnos. */
1439
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1440
                           socklen_t addrlen)
1441
{
1442
    void *addr;
1443

    
1444
    if (addrlen < 0)
1445
        return -TARGET_EINVAL;
1446

    
1447
    addr = alloca(addrlen);
1448

    
1449
    target_to_host_sockaddr(addr, target_addr, addrlen);
1450
    return get_errno(connect(sockfd, addr, addrlen));
1451
}
1452

    
1453
/* do_sendrecvmsg() Must return target values and target errnos. */
1454
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1455
                               int flags, int send)
1456
{
1457
    abi_long ret, len;
1458
    struct target_msghdr *msgp;
1459
    struct msghdr msg;
1460
    int count;
1461
    struct iovec *vec;
1462
    abi_ulong target_vec;
1463

    
1464
    /* FIXME */
1465
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1466
                          msgp,
1467
                          target_msg,
1468
                          send ? 1 : 0))
1469
        return -TARGET_EFAULT;
1470
    if (msgp->msg_name) {
1471
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1472
        msg.msg_name = alloca(msg.msg_namelen);
1473
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1474
                                msg.msg_namelen);
1475
    } else {
1476
        msg.msg_name = NULL;
1477
        msg.msg_namelen = 0;
1478
    }
1479
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1480
    msg.msg_control = alloca(msg.msg_controllen);
1481
    msg.msg_flags = tswap32(msgp->msg_flags);
1482

    
1483
    count = tswapl(msgp->msg_iovlen);
1484
    vec = alloca(count * sizeof(struct iovec));
1485
    target_vec = tswapl(msgp->msg_iov);
1486
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1487
    msg.msg_iovlen = count;
1488
    msg.msg_iov = vec;
1489

    
1490
    if (send) {
1491
        ret = target_to_host_cmsg(&msg, msgp);
1492
        if (ret == 0)
1493
            ret = get_errno(sendmsg(fd, &msg, flags));
1494
    } else {
1495
        ret = get_errno(recvmsg(fd, &msg, flags));
1496
        if (!is_error(ret)) {
1497
            len = ret;
1498
            ret = host_to_target_cmsg(msgp, &msg);
1499
            if (!is_error(ret))
1500
                ret = len;
1501
        }
1502
    }
1503
    unlock_iovec(vec, target_vec, count, !send);
1504
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1505
    return ret;
1506
}
1507

    
1508
/* do_accept() Must return target values and target errnos. */
1509
static abi_long do_accept(int fd, abi_ulong target_addr,
1510
                          abi_ulong target_addrlen_addr)
1511
{
1512
    socklen_t addrlen;
1513
    void *addr;
1514
    abi_long ret;
1515

    
1516
    if (get_user_u32(addrlen, target_addrlen_addr))
1517
        return -TARGET_EFAULT;
1518

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

    
1522
    addr = alloca(addrlen);
1523

    
1524
    ret = get_errno(accept(fd, addr, &addrlen));
1525
    if (!is_error(ret)) {
1526
        host_to_target_sockaddr(target_addr, addr, addrlen);
1527
        if (put_user_u32(addrlen, target_addrlen_addr))
1528
            ret = -TARGET_EFAULT;
1529
    }
1530
    return ret;
1531
}
1532

    
1533
/* do_getpeername() Must return target values and target errnos. */
1534
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1535
                               abi_ulong target_addrlen_addr)
1536
{
1537
    socklen_t addrlen;
1538
    void *addr;
1539
    abi_long ret;
1540

    
1541
    if (get_user_u32(addrlen, target_addrlen_addr))
1542
        return -TARGET_EFAULT;
1543

    
1544
    if (addrlen < 0)
1545
        return -TARGET_EINVAL;
1546

    
1547
    addr = alloca(addrlen);
1548

    
1549
    ret = get_errno(getpeername(fd, addr, &addrlen));
1550
    if (!is_error(ret)) {
1551
        host_to_target_sockaddr(target_addr, addr, addrlen);
1552
        if (put_user_u32(addrlen, target_addrlen_addr))
1553
            ret = -TARGET_EFAULT;
1554
    }
1555
    return ret;
1556
}
1557

    
1558
/* do_getsockname() Must return target values and target errnos. */
1559
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1560
                               abi_ulong target_addrlen_addr)
1561
{
1562
    socklen_t addrlen;
1563
    void *addr;
1564
    abi_long ret;
1565

    
1566
    if (target_addr == 0)
1567
       return get_errno(accept(fd, NULL, NULL));
1568

    
1569
    if (get_user_u32(addrlen, target_addrlen_addr))
1570
        return -TARGET_EFAULT;
1571

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

    
1575
    addr = alloca(addrlen);
1576

    
1577
    ret = get_errno(getsockname(fd, addr, &addrlen));
1578
    if (!is_error(ret)) {
1579
        host_to_target_sockaddr(target_addr, addr, addrlen);
1580
        if (put_user_u32(addrlen, target_addrlen_addr))
1581
            ret = -TARGET_EFAULT;
1582
    }
1583
    return ret;
1584
}
1585

    
1586
/* do_socketpair() Must return target values and target errnos. */
1587
static abi_long do_socketpair(int domain, int type, int protocol,
1588
                              abi_ulong target_tab_addr)
1589
{
1590
    int tab[2];
1591
    abi_long ret;
1592

    
1593
    ret = get_errno(socketpair(domain, type, protocol, tab));
1594
    if (!is_error(ret)) {
1595
        if (put_user_s32(tab[0], target_tab_addr)
1596
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1597
            ret = -TARGET_EFAULT;
1598
    }
1599
    return ret;
1600
}
1601

    
1602
/* do_sendto() Must return target values and target errnos. */
1603
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1604
                          abi_ulong target_addr, socklen_t addrlen)
1605
{
1606
    void *addr;
1607
    void *host_msg;
1608
    abi_long ret;
1609

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

    
1613
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1614
    if (!host_msg)
1615
        return -TARGET_EFAULT;
1616
    if (target_addr) {
1617
        addr = alloca(addrlen);
1618
        target_to_host_sockaddr(addr, target_addr, addrlen);
1619
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1620
    } else {
1621
        ret = get_errno(send(fd, host_msg, len, flags));
1622
    }
1623
    unlock_user(host_msg, msg, 0);
1624
    return ret;
1625
}
1626

    
1627
/* do_recvfrom() Must return target values and target errnos. */
1628
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1629
                            abi_ulong target_addr,
1630
                            abi_ulong target_addrlen)
1631
{
1632
    socklen_t addrlen;
1633
    void *addr;
1634
    void *host_msg;
1635
    abi_long ret;
1636

    
1637
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1638
    if (!host_msg)
1639
        return -TARGET_EFAULT;
1640
    if (target_addr) {
1641
        if (get_user_u32(addrlen, target_addrlen)) {
1642
            ret = -TARGET_EFAULT;
1643
            goto fail;
1644
        }
1645
        if (addrlen < 0) {
1646
            ret = -TARGET_EINVAL;
1647
            goto fail;
1648
        }
1649
        addr = alloca(addrlen);
1650
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1651
    } else {
1652
        addr = NULL; /* To keep compiler quiet.  */
1653
        ret = get_errno(recv(fd, host_msg, len, flags));
1654
    }
1655
    if (!is_error(ret)) {
1656
        if (target_addr) {
1657
            host_to_target_sockaddr(target_addr, addr, addrlen);
1658
            if (put_user_u32(addrlen, target_addrlen)) {
1659
                ret = -TARGET_EFAULT;
1660
                goto fail;
1661
            }
1662
        }
1663
        unlock_user(host_msg, msg, len);
1664
    } else {
1665
fail:
1666
        unlock_user(host_msg, msg, 0);
1667
    }
1668
    return ret;
1669
}
1670

    
1671
#ifdef TARGET_NR_socketcall
1672
/* do_socketcall() Must return target values and target errnos. */
1673
static abi_long do_socketcall(int num, abi_ulong vptr)
1674
{
1675
    abi_long ret;
1676
    const int n = sizeof(abi_ulong);
1677

    
1678
    switch(num) {
1679
    case SOCKOP_socket:
1680
        {
1681
            int domain, type, protocol;
1682

    
1683
            if (get_user_s32(domain, vptr)
1684
                || get_user_s32(type, vptr + n)
1685
                || get_user_s32(protocol, vptr + 2 * n))
1686
                return -TARGET_EFAULT;
1687

    
1688
            ret = do_socket(domain, type, protocol);
1689
        }
1690
        break;
1691
    case SOCKOP_bind:
1692
        {
1693
            int sockfd;
1694
            abi_ulong target_addr;
1695
            socklen_t addrlen;
1696

    
1697
            if (get_user_s32(sockfd, vptr)
1698
                || get_user_ual(target_addr, vptr + n)
1699
                || get_user_u32(addrlen, vptr + 2 * n))
1700
                return -TARGET_EFAULT;
1701

    
1702
            ret = do_bind(sockfd, target_addr, addrlen);
1703
        }
1704
        break;
1705
    case SOCKOP_connect:
1706
        {
1707
            int sockfd;
1708
            abi_ulong target_addr;
1709
            socklen_t addrlen;
1710

    
1711
            if (get_user_s32(sockfd, vptr)
1712
                || get_user_ual(target_addr, vptr + n)
1713
                || get_user_u32(addrlen, vptr + 2 * n))
1714
                return -TARGET_EFAULT;
1715

    
1716
            ret = do_connect(sockfd, target_addr, addrlen);
1717
        }
1718
        break;
1719
    case SOCKOP_listen:
1720
        {
1721
            int sockfd, backlog;
1722

    
1723
            if (get_user_s32(sockfd, vptr)
1724
                || get_user_s32(backlog, vptr + n))
1725
                return -TARGET_EFAULT;
1726

    
1727
            ret = get_errno(listen(sockfd, backlog));
1728
        }
1729
        break;
1730
    case SOCKOP_accept:
1731
        {
1732
            int sockfd;
1733
            abi_ulong target_addr, target_addrlen;
1734

    
1735
            if (get_user_s32(sockfd, vptr)
1736
                || get_user_ual(target_addr, vptr + n)
1737
                || get_user_u32(target_addrlen, vptr + 2 * n))
1738
                return -TARGET_EFAULT;
1739

    
1740
            ret = do_accept(sockfd, target_addr, target_addrlen);
1741
        }
1742
        break;
1743
    case SOCKOP_getsockname:
1744
        {
1745
            int sockfd;
1746
            abi_ulong target_addr, target_addrlen;
1747

    
1748
            if (get_user_s32(sockfd, vptr)
1749
                || get_user_ual(target_addr, vptr + n)
1750
                || get_user_u32(target_addrlen, vptr + 2 * n))
1751
                return -TARGET_EFAULT;
1752

    
1753
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1754
        }
1755
        break;
1756
    case SOCKOP_getpeername:
1757
        {
1758
            int sockfd;
1759
            abi_ulong target_addr, target_addrlen;
1760

    
1761
            if (get_user_s32(sockfd, vptr)
1762
                || get_user_ual(target_addr, vptr + n)
1763
                || get_user_u32(target_addrlen, vptr + 2 * n))
1764
                return -TARGET_EFAULT;
1765

    
1766
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1767
        }
1768
        break;
1769
    case SOCKOP_socketpair:
1770
        {
1771
            int domain, type, protocol;
1772
            abi_ulong tab;
1773

    
1774
            if (get_user_s32(domain, vptr)
1775
                || get_user_s32(type, vptr + n)
1776
                || get_user_s32(protocol, vptr + 2 * n)
1777
                || get_user_ual(tab, vptr + 3 * n))
1778
                return -TARGET_EFAULT;
1779

    
1780
            ret = do_socketpair(domain, type, protocol, tab);
1781
        }
1782
        break;
1783
    case SOCKOP_send:
1784
        {
1785
            int sockfd;
1786
            abi_ulong msg;
1787
            size_t len;
1788
            int flags;
1789

    
1790
            if (get_user_s32(sockfd, vptr)
1791
                || get_user_ual(msg, vptr + n)
1792
                || get_user_ual(len, vptr + 2 * n)
1793
                || get_user_s32(flags, vptr + 3 * n))
1794
                return -TARGET_EFAULT;
1795

    
1796
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1797
        }
1798
        break;
1799
    case SOCKOP_recv:
1800
        {
1801
            int sockfd;
1802
            abi_ulong msg;
1803
            size_t len;
1804
            int flags;
1805

    
1806
            if (get_user_s32(sockfd, vptr)
1807
                || get_user_ual(msg, vptr + n)
1808
                || get_user_ual(len, vptr + 2 * n)
1809
                || get_user_s32(flags, vptr + 3 * n))
1810
                return -TARGET_EFAULT;
1811

    
1812
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1813
        }
1814
        break;
1815
    case SOCKOP_sendto:
1816
        {
1817
            int sockfd;
1818
            abi_ulong msg;
1819
            size_t len;
1820
            int flags;
1821
            abi_ulong addr;
1822
            socklen_t addrlen;
1823

    
1824
            if (get_user_s32(sockfd, vptr)
1825
                || get_user_ual(msg, vptr + n)
1826
                || get_user_ual(len, vptr + 2 * n)
1827
                || get_user_s32(flags, vptr + 3 * n)
1828
                || get_user_ual(addr, vptr + 4 * n)
1829
                || get_user_u32(addrlen, vptr + 5 * n))
1830
                return -TARGET_EFAULT;
1831

    
1832
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1833
        }
1834
        break;
1835
    case SOCKOP_recvfrom:
1836
        {
1837
            int sockfd;
1838
            abi_ulong msg;
1839
            size_t len;
1840
            int flags;
1841
            abi_ulong addr;
1842
            socklen_t addrlen;
1843

    
1844
            if (get_user_s32(sockfd, vptr)
1845
                || get_user_ual(msg, vptr + n)
1846
                || get_user_ual(len, vptr + 2 * n)
1847
                || get_user_s32(flags, vptr + 3 * n)
1848
                || get_user_ual(addr, vptr + 4 * n)
1849
                || get_user_u32(addrlen, vptr + 5 * n))
1850
                return -TARGET_EFAULT;
1851

    
1852
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1853
        }
1854
        break;
1855
    case SOCKOP_shutdown:
1856
        {
1857
            int sockfd, how;
1858

    
1859
            if (get_user_s32(sockfd, vptr)
1860
                || get_user_s32(how, vptr + n))
1861
                return -TARGET_EFAULT;
1862

    
1863
            ret = get_errno(shutdown(sockfd, how));
1864
        }
1865
        break;
1866
    case SOCKOP_sendmsg:
1867
    case SOCKOP_recvmsg:
1868
        {
1869
            int fd;
1870
            abi_ulong target_msg;
1871
            int flags;
1872

    
1873
            if (get_user_s32(fd, vptr)
1874
                || get_user_ual(target_msg, vptr + n)
1875
                || get_user_s32(flags, vptr + 2 * n))
1876
                return -TARGET_EFAULT;
1877

    
1878
            ret = do_sendrecvmsg(fd, target_msg, flags,
1879
                                 (num == SOCKOP_sendmsg));
1880
        }
1881
        break;
1882
    case SOCKOP_setsockopt:
1883
        {
1884
            int sockfd;
1885
            int level;
1886
            int optname;
1887
            abi_ulong optval;
1888
            socklen_t optlen;
1889

    
1890
            if (get_user_s32(sockfd, vptr)
1891
                || get_user_s32(level, vptr + n)
1892
                || get_user_s32(optname, vptr + 2 * n)
1893
                || get_user_ual(optval, vptr + 3 * n)
1894
                || get_user_u32(optlen, vptr + 4 * n))
1895
                return -TARGET_EFAULT;
1896

    
1897
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1898
        }
1899
        break;
1900
    case SOCKOP_getsockopt:
1901
        {
1902
            int sockfd;
1903
            int level;
1904
            int optname;
1905
            abi_ulong optval;
1906
            socklen_t optlen;
1907

    
1908
            if (get_user_s32(sockfd, vptr)
1909
                || get_user_s32(level, vptr + n)
1910
                || get_user_s32(optname, vptr + 2 * n)
1911
                || get_user_ual(optval, vptr + 3 * n)
1912
                || get_user_u32(optlen, vptr + 4 * n))
1913
                return -TARGET_EFAULT;
1914

    
1915
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1916
        }
1917
        break;
1918
    default:
1919
        gemu_log("Unsupported socketcall: %d\n", num);
1920
        ret = -TARGET_ENOSYS;
1921
        break;
1922
    }
1923
    return ret;
1924
}
1925
#endif
1926

    
1927
#ifdef TARGET_NR_ipc
1928
#define N_SHM_REGIONS        32
1929

    
1930
static struct shm_region {
1931
    abi_ulong        start;
1932
    abi_ulong        size;
1933
} shm_regions[N_SHM_REGIONS];
1934
#endif
1935

    
1936
struct target_ipc_perm
1937
{
1938
    abi_long __key;
1939
    abi_ulong uid;
1940
    abi_ulong gid;
1941
    abi_ulong cuid;
1942
    abi_ulong cgid;
1943
    unsigned short int mode;
1944
    unsigned short int __pad1;
1945
    unsigned short int __seq;
1946
    unsigned short int __pad2;
1947
    abi_ulong __unused1;
1948
    abi_ulong __unused2;
1949
};
1950

    
1951
struct target_semid_ds
1952
{
1953
  struct target_ipc_perm sem_perm;
1954
  abi_ulong sem_otime;
1955
  abi_ulong __unused1;
1956
  abi_ulong sem_ctime;
1957
  abi_ulong __unused2;
1958
  abi_ulong sem_nsems;
1959
  abi_ulong __unused3;
1960
  abi_ulong __unused4;
1961
};
1962

    
1963
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1964
                                               abi_ulong target_addr)
1965
{
1966
    struct target_ipc_perm *target_ip;
1967
    struct target_semid_ds *target_sd;
1968

    
1969
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1970
        return -TARGET_EFAULT;
1971
    target_ip=&(target_sd->sem_perm);
1972
    host_ip->__key = tswapl(target_ip->__key);
1973
    host_ip->uid = tswapl(target_ip->uid);
1974
    host_ip->gid = tswapl(target_ip->gid);
1975
    host_ip->cuid = tswapl(target_ip->cuid);
1976
    host_ip->cgid = tswapl(target_ip->cgid);
1977
    host_ip->mode = tswapl(target_ip->mode);
1978
    unlock_user_struct(target_sd, target_addr, 0);
1979
    return 0;
1980
}
1981

    
1982
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1983
                                               struct ipc_perm *host_ip)
1984
{
1985
    struct target_ipc_perm *target_ip;
1986
    struct target_semid_ds *target_sd;
1987

    
1988
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1989
        return -TARGET_EFAULT;
1990
    target_ip = &(target_sd->sem_perm);
1991
    target_ip->__key = tswapl(host_ip->__key);
1992
    target_ip->uid = tswapl(host_ip->uid);
1993
    target_ip->gid = tswapl(host_ip->gid);
1994
    target_ip->cuid = tswapl(host_ip->cuid);
1995
    target_ip->cgid = tswapl(host_ip->cgid);
1996
    target_ip->mode = tswapl(host_ip->mode);
1997
    unlock_user_struct(target_sd, target_addr, 1);
1998
    return 0;
1999
}
2000

    
2001
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2002
                                               abi_ulong target_addr)
2003
{
2004
    struct target_semid_ds *target_sd;
2005

    
2006
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2007
        return -TARGET_EFAULT;
2008
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
2009
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2010
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2011
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2012
    unlock_user_struct(target_sd, target_addr, 0);
2013
    return 0;
2014
}
2015

    
2016
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2017
                                               struct semid_ds *host_sd)
2018
{
2019
    struct target_semid_ds *target_sd;
2020

    
2021
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2022
        return -TARGET_EFAULT;
2023
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
2024
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2025
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2026
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2027
    unlock_user_struct(target_sd, target_addr, 1);
2028
    return 0;
2029
}
2030

    
2031
union semun {
2032
        int val;
2033
        struct semid_ds *buf;
2034
        unsigned short *array;
2035
};
2036

    
2037
union target_semun {
2038
        int val;
2039
        abi_long buf;
2040
        unsigned short int *array;
2041
};
2042

    
2043
static inline abi_long target_to_host_semun(int cmd,
2044
                                            union semun *host_su,
2045
                                            abi_ulong target_addr,
2046
                                            struct semid_ds *ds)
2047
{
2048
    union target_semun *target_su;
2049

    
2050
    switch( cmd ) {
2051
        case IPC_STAT:
2052
        case IPC_SET:
2053
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
2054
               return -TARGET_EFAULT;
2055
           target_to_host_semid_ds(ds,target_su->buf);
2056
           host_su->buf = ds;
2057
           unlock_user_struct(target_su, target_addr, 0);
2058
           break;
2059
        case GETVAL:
2060
        case SETVAL:
2061
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
2062
               return -TARGET_EFAULT;
2063
           host_su->val = tswapl(target_su->val);
2064
           unlock_user_struct(target_su, target_addr, 0);
2065
           break;
2066
        case GETALL:
2067
        case SETALL:
2068
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
2069
               return -TARGET_EFAULT;
2070
           *host_su->array = tswap16(*target_su->array);
2071
           unlock_user_struct(target_su, target_addr, 0);
2072
           break;
2073
        default:
2074
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
2075
    }
2076
    return 0;
2077
}
2078

    
2079
static inline abi_long host_to_target_semun(int cmd,
2080
                                            abi_ulong target_addr,
2081
                                            union semun *host_su,
2082
                                            struct semid_ds *ds)
2083
{
2084
    union target_semun *target_su;
2085

    
2086
    switch( cmd ) {
2087
        case IPC_STAT:
2088
        case IPC_SET:
2089
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
2090
               return -TARGET_EFAULT;
2091
           host_to_target_semid_ds(target_su->buf,ds);
2092
           unlock_user_struct(target_su, target_addr, 1);
2093
           break;
2094
        case GETVAL:
2095
        case SETVAL:
2096
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
2097
               return -TARGET_EFAULT;
2098
           target_su->val = tswapl(host_su->val);
2099
           unlock_user_struct(target_su, target_addr, 1);
2100
           break;
2101
        case GETALL:
2102
        case SETALL:
2103
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
2104
               return -TARGET_EFAULT;
2105
           *target_su->array = tswap16(*host_su->array);
2106
           unlock_user_struct(target_su, target_addr, 1);
2107
           break;
2108
        default:
2109
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
2110
    }
2111
    return 0;
2112
}
2113

    
2114
static inline abi_long do_semctl(int first, int second, int third,
2115
                                 abi_long ptr)
2116
{
2117
    union semun arg;
2118
    struct semid_ds dsarg;
2119
    int cmd = third&0xff;
2120
    abi_long ret = 0;
2121

    
2122
    switch( cmd ) {
2123
        case GETVAL:
2124
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
2125
            ret = get_errno(semctl(first, second, cmd, arg));
2126
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
2127
            break;
2128
        case SETVAL:
2129
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
2130
            ret = get_errno(semctl(first, second, cmd, arg));
2131
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
2132
            break;
2133
        case GETALL:
2134
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
2135
            ret = get_errno(semctl(first, second, cmd, arg));
2136
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
2137
            break;
2138
        case SETALL:
2139
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
2140
            ret = get_errno(semctl(first, second, cmd, arg));
2141
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
2142
            break;
2143
        case IPC_STAT:
2144
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
2145
            ret = get_errno(semctl(first, second, cmd, arg));
2146
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
2147
            break;
2148
        case IPC_SET:
2149
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
2150
            ret = get_errno(semctl(first, second, cmd, arg));
2151
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
2152
            break;
2153
    default:
2154
            ret = get_errno(semctl(first, second, cmd, arg));
2155
    }
2156

    
2157
    return ret;
2158
}
2159

    
2160
struct target_msqid_ds
2161
{
2162
    struct target_ipc_perm msg_perm;
2163
    abi_ulong msg_stime;
2164
#if TARGET_ABI_BITS == 32
2165
    abi_ulong __unused1;
2166
#endif
2167
    abi_ulong msg_rtime;
2168
#if TARGET_ABI_BITS == 32
2169
    abi_ulong __unused2;
2170
#endif
2171
    abi_ulong msg_ctime;
2172
#if TARGET_ABI_BITS == 32
2173
    abi_ulong __unused3;
2174
#endif
2175
    abi_ulong __msg_cbytes;
2176
    abi_ulong msg_qnum;
2177
    abi_ulong msg_qbytes;
2178
    abi_ulong msg_lspid;
2179
    abi_ulong msg_lrpid;
2180
    abi_ulong __unused4;
2181
    abi_ulong __unused5;
2182
};
2183

    
2184
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2185
                                               abi_ulong target_addr)
2186
{
2187
    struct target_msqid_ds *target_md;
2188

    
2189
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2190
        return -TARGET_EFAULT;
2191
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2192
        return -TARGET_EFAULT;
2193
    host_md->msg_stime = tswapl(target_md->msg_stime);
2194
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2195
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2196
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2197
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2198
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2199
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2200
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2201
    unlock_user_struct(target_md, target_addr, 0);
2202
    return 0;
2203
}
2204

    
2205
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2206
                                               struct msqid_ds *host_md)
2207
{
2208
    struct target_msqid_ds *target_md;
2209

    
2210
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2211
        return -TARGET_EFAULT;
2212
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2213
        return -TARGET_EFAULT;
2214
    target_md->msg_stime = tswapl(host_md->msg_stime);
2215
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2216
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2217
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2218
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2219
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2220
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2221
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2222
    unlock_user_struct(target_md, target_addr, 1);
2223
    return 0;
2224
}
2225

    
2226
struct target_msginfo {
2227
    int msgpool;
2228
    int msgmap;
2229
    int msgmax;
2230
    int msgmnb;
2231
    int msgmni;
2232
    int msgssz;
2233
    int msgtql;
2234
    unsigned short int msgseg;
2235
};
2236

    
2237
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2238
                                              struct msginfo *host_msginfo)
2239
{
2240
    struct target_msginfo *target_msginfo;
2241
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2242
        return -TARGET_EFAULT;
2243
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2244
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2245
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2246
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2247
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2248
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2249
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2250
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2251
    unlock_user_struct(target_msginfo, target_addr, 1);
2252
    return 0;
2253
}
2254

    
2255
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2256
{
2257
    struct msqid_ds dsarg;
2258
    struct msginfo msginfo;
2259
    abi_long ret = -TARGET_EINVAL;
2260

    
2261
    cmd &= 0xff;
2262

    
2263
    switch (cmd) {
2264
    case IPC_STAT:
2265
    case IPC_SET:
2266
    case MSG_STAT:
2267
        if (target_to_host_msqid_ds(&dsarg,ptr))
2268
            return -TARGET_EFAULT;
2269
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2270
        if (host_to_target_msqid_ds(ptr,&dsarg))
2271
            return -TARGET_EFAULT;
2272
        break;
2273
    case IPC_RMID:
2274
        ret = get_errno(msgctl(msgid, cmd, NULL));
2275
        break;
2276
    case IPC_INFO:
2277
    case MSG_INFO:
2278
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2279
        if (host_to_target_msginfo(ptr, &msginfo))
2280
            return -TARGET_EFAULT;
2281
        break;
2282
    }
2283

    
2284
    return ret;
2285
}
2286

    
2287
struct target_msgbuf {
2288
    abi_long mtype;
2289
    char        mtext[1];
2290
};
2291

    
2292
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2293
                                 unsigned int msgsz, int msgflg)
2294
{
2295
    struct target_msgbuf *target_mb;
2296
    struct msgbuf *host_mb;
2297
    abi_long ret = 0;
2298

    
2299
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2300
        return -TARGET_EFAULT;
2301
    host_mb = malloc(msgsz+sizeof(long));
2302
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2303
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2304
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2305
    free(host_mb);
2306
    unlock_user_struct(target_mb, msgp, 0);
2307

    
2308
    return ret;
2309
}
2310

    
2311
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2312
                                 unsigned int msgsz, abi_long msgtyp,
2313
                                 int msgflg)
2314
{
2315
    struct target_msgbuf *target_mb;
2316
    char *target_mtext;
2317
    struct msgbuf *host_mb;
2318
    abi_long ret = 0;
2319

    
2320
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2321
        return -TARGET_EFAULT;
2322

    
2323
    host_mb = malloc(msgsz+sizeof(long));
2324
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2325

    
2326
    if (ret > 0) {
2327
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2328
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2329
        if (!target_mtext) {
2330
            ret = -TARGET_EFAULT;
2331
            goto end;
2332
        }
2333
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2334
        unlock_user(target_mtext, target_mtext_addr, ret);
2335
    }
2336

    
2337
    target_mb->mtype = tswapl(host_mb->mtype);
2338
    free(host_mb);
2339

    
2340
end:
2341
    if (target_mb)
2342
        unlock_user_struct(target_mb, msgp, 1);
2343
    return ret;
2344
}
2345

    
2346
#ifdef TARGET_NR_ipc
2347
/* ??? This only works with linear mappings.  */
2348
/* do_ipc() must return target values and target errnos. */
2349
static abi_long do_ipc(unsigned int call, int first,
2350
                       int second, int third,
2351
                       abi_long ptr, abi_long fifth)
2352
{
2353
    int version;
2354
    abi_long ret = 0;
2355
    struct shmid_ds shm_info;
2356
    int i;
2357

    
2358
    version = call >> 16;
2359
    call &= 0xffff;
2360

    
2361
    switch (call) {
2362
    case IPCOP_semop:
2363
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2364
        break;
2365

    
2366
    case IPCOP_semget:
2367
        ret = get_errno(semget(first, second, third));
2368
        break;
2369

    
2370
    case IPCOP_semctl:
2371
        ret = do_semctl(first, second, third, ptr);
2372
        break;
2373

    
2374
    case IPCOP_semtimedop:
2375
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2376
        ret = -TARGET_ENOSYS;
2377
        break;
2378

    
2379
    case IPCOP_msgget:
2380
        ret = get_errno(msgget(first, second));
2381
        break;
2382

    
2383
    case IPCOP_msgsnd:
2384
        ret = do_msgsnd(first, ptr, second, third);
2385
        break;
2386

    
2387
    case IPCOP_msgctl:
2388
        ret = do_msgctl(first, second, ptr);
2389
        break;
2390

    
2391
    case IPCOP_msgrcv:
2392
        switch (version) {
2393
        case 0:
2394
            {
2395
                struct target_ipc_kludge {
2396
                    abi_long msgp;
2397
                    abi_long msgtyp;
2398
                } *tmp;
2399

    
2400
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2401
                    ret = -TARGET_EFAULT;
2402
                    break;
2403
                }
2404

    
2405
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2406

    
2407
                unlock_user_struct(tmp, ptr, 0);
2408
                break;
2409
            }
2410
        default:
2411
            ret = do_msgrcv(first, ptr, second, fifth, third);
2412
        }
2413
        break;
2414

    
2415
    case IPCOP_shmat:
2416
        {
2417
            abi_ulong raddr;
2418
            void *host_addr;
2419
            /* SHM_* flags are the same on all linux platforms */
2420
            host_addr = shmat(first, (void *)g2h(ptr), second);
2421
            if (host_addr == (void *)-1) {
2422
                ret = get_errno((long)host_addr);
2423
                break;
2424
            }
2425
            raddr = h2g((unsigned long)host_addr);
2426
            /* find out the length of the shared memory segment */
2427
            
2428
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2429
            if (is_error(ret)) {
2430
                /* can't get length, bail out */
2431
                shmdt(host_addr);
2432
                break;
2433
            }
2434
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2435
                           PAGE_VALID | PAGE_READ |
2436
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2437
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2438
                if (shm_regions[i].start == 0) {
2439
                    shm_regions[i].start = raddr;
2440
                    shm_regions[i].size = shm_info.shm_segsz;
2441
                    break;
2442
                }
2443
            }
2444
            if (put_user_ual(raddr, third))
2445
                return -TARGET_EFAULT;
2446
            ret = 0;
2447
        }
2448
        break;
2449
    case IPCOP_shmdt:
2450
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2451
            if (shm_regions[i].start == ptr) {
2452
                shm_regions[i].start = 0;
2453
                page_set_flags(ptr, shm_regions[i].size, 0);
2454
                break;
2455
            }
2456
        }
2457
        ret = get_errno(shmdt((void *)g2h(ptr)));
2458
        break;
2459

    
2460
    case IPCOP_shmget:
2461
        /* IPC_* flag values are the same on all linux platforms */
2462
        ret = get_errno(shmget(first, second, third));
2463
        break;
2464

    
2465
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2466
    case IPCOP_shmctl:
2467
        switch(second) {
2468
        case IPC_RMID:
2469
        case SHM_LOCK:
2470
        case SHM_UNLOCK:
2471
            ret = get_errno(shmctl(first, second, NULL));
2472
            break;
2473
        default:
2474
            goto unimplemented;
2475
        }
2476
        break;
2477
    default:
2478
    unimplemented:
2479
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2480
        ret = -TARGET_ENOSYS;
2481
        break;
2482
    }
2483
    return ret;
2484
}
2485
#endif
2486

    
2487
/* kernel structure types definitions */
2488
#define IFNAMSIZ        16
2489

    
2490
#define STRUCT(name, list...) STRUCT_ ## name,
2491
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2492
enum {
2493
#include "syscall_types.h"
2494
};
2495
#undef STRUCT
2496
#undef STRUCT_SPECIAL
2497

    
2498
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2499
#define STRUCT_SPECIAL(name)
2500
#include "syscall_types.h"
2501
#undef STRUCT
2502
#undef STRUCT_SPECIAL
2503

    
2504
typedef struct IOCTLEntry {
2505
    unsigned int target_cmd;
2506
    unsigned int host_cmd;
2507
    const char *name;
2508
    int access;
2509
    const argtype arg_type[5];
2510
} IOCTLEntry;
2511

    
2512
#define IOC_R 0x0001
2513
#define IOC_W 0x0002
2514
#define IOC_RW (IOC_R | IOC_W)
2515

    
2516
#define MAX_STRUCT_SIZE 4096
2517

    
2518
static IOCTLEntry ioctl_entries[] = {
2519
#define IOCTL(cmd, access, types...) \
2520
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2521
#include "ioctls.h"
2522
    { 0, 0, },
2523
};
2524

    
2525
/* ??? Implement proper locking for ioctls.  */
2526
/* do_ioctl() Must return target values and target errnos. */
2527
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2528
{
2529
    const IOCTLEntry *ie;
2530
    const argtype *arg_type;
2531
    abi_long ret;
2532
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2533
    int target_size;
2534
    void *argptr;
2535

    
2536
    ie = ioctl_entries;
2537
    for(;;) {
2538
        if (ie->target_cmd == 0) {
2539
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2540
            return -TARGET_ENOSYS;
2541
        }
2542
        if (ie->target_cmd == cmd)
2543
            break;
2544
        ie++;
2545
    }
2546
    arg_type = ie->arg_type;
2547
#if defined(DEBUG)
2548
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2549
#endif
2550
    switch(arg_type[0]) {
2551
    case TYPE_NULL:
2552
        /* no argument */
2553
        ret = get_errno(ioctl(fd, ie->host_cmd));
2554
        break;
2555
    case TYPE_PTRVOID:
2556
    case TYPE_INT:
2557
        /* int argment */
2558
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2559
        break;
2560
    case TYPE_PTR:
2561
        arg_type++;
2562
        target_size = thunk_type_size(arg_type, 0);
2563
        switch(ie->access) {
2564
        case IOC_R:
2565
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2566
            if (!is_error(ret)) {
2567
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2568
                if (!argptr)
2569
                    return -TARGET_EFAULT;
2570
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2571
                unlock_user(argptr, arg, target_size);
2572
            }
2573
            break;
2574
        case IOC_W:
2575
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2576
            if (!argptr)
2577
                return -TARGET_EFAULT;
2578
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2579
            unlock_user(argptr, arg, 0);
2580
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2581
            break;
2582
        default:
2583
        case IOC_RW:
2584
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2585
            if (!argptr)
2586
                return -TARGET_EFAULT;
2587
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2588
            unlock_user(argptr, arg, 0);
2589
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2590
            if (!is_error(ret)) {
2591
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2592
                if (!argptr)
2593
                    return -TARGET_EFAULT;
2594
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2595
                unlock_user(argptr, arg, target_size);
2596
            }
2597
            break;
2598
        }
2599
        break;
2600
    default:
2601
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2602
                 (long)cmd, arg_type[0]);
2603
        ret = -TARGET_ENOSYS;
2604
        break;
2605
    }
2606
    return ret;
2607
}
2608

    
2609
static const bitmask_transtbl iflag_tbl[] = {
2610
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2611
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2612
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2613
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2614
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2615
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2616
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2617
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2618
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2619
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2620
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2621
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2622
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2623
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2624
        { 0, 0, 0, 0 }
2625
};
2626

    
2627
static const bitmask_transtbl oflag_tbl[] = {
2628
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2629
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2630
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2631
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2632
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2633
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2634
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2635
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2636
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2637
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2638
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2639
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2640
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2641
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2642
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2643
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2644
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2645
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2646
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2647
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2648
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2649
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2650
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2651
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2652
        { 0, 0, 0, 0 }
2653
};
2654

    
2655
static const bitmask_transtbl cflag_tbl[] = {
2656
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2657
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2658
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2659
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2660
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2661
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2662
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2663
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2664
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2665
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2666
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2667
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2668
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2669
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2670
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2671
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2672
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2673
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2674
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2675
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2676
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2677
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2678
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2679
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2680
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2681
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2682
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2683
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2684
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2685
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2686
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2687
        { 0, 0, 0, 0 }
2688
};
2689

    
2690
static const bitmask_transtbl lflag_tbl[] = {
2691
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2692
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2693
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2694
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2695
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2696
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2697
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2698
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2699
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2700
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2701
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2702
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2703
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2704
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2705
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2706
        { 0, 0, 0, 0 }
2707
};
2708

    
2709
static void target_to_host_termios (void *dst, const void *src)
2710
{
2711
    struct host_termios *host = dst;
2712
    const struct target_termios *target = src;
2713

    
2714
    host->c_iflag =
2715
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2716
    host->c_oflag =
2717
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2718
    host->c_cflag =
2719
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2720
    host->c_lflag =
2721
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2722
    host->c_line = target->c_line;
2723

    
2724
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2725
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2726
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2727
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2728
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2729
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2730
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2731
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2732
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2733
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2734
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2735
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2736
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2737
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2738
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2739
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2740
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2741
}
2742

    
2743
static void host_to_target_termios (void *dst, const void *src)
2744
{
2745
    struct target_termios *target = dst;
2746
    const struct host_termios *host = src;
2747

    
2748
    target->c_iflag =
2749
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2750
    target->c_oflag =
2751
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2752
    target->c_cflag =
2753
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2754
    target->c_lflag =
2755
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2756
    target->c_line = host->c_line;
2757

    
2758
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2759
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2760
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2761
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2762
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2763
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2764
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2765
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2766
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2767
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2768
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2769
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2770
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2771
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2772
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2773
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2774
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2775
}
2776

    
2777
static const StructEntry struct_termios_def = {
2778
    .convert = { host_to_target_termios, target_to_host_termios },
2779
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2780
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2781
};
2782

    
2783
static bitmask_transtbl mmap_flags_tbl[] = {
2784
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2785
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2786
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2787
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2788
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2789
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2790
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2791
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2792
        { 0, 0, 0, 0 }
2793
};
2794

    
2795
#if defined(TARGET_I386)
2796

    
2797
/* NOTE: there is really one LDT for all the threads */
2798
static uint8_t *ldt_table;
2799

    
2800
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2801
{
2802
    int size;
2803
    void *p;
2804

    
2805
    if (!ldt_table)
2806
        return 0;
2807
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2808
    if (size > bytecount)
2809
        size = bytecount;
2810
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2811
    if (!p)
2812
        return -TARGET_EFAULT;
2813
    /* ??? Should this by byteswapped?  */
2814
    memcpy(p, ldt_table, size);
2815
    unlock_user(p, ptr, size);
2816
    return size;
2817
}
2818

    
2819
/* XXX: add locking support */
2820
static abi_long write_ldt(CPUX86State *env,
2821
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2822
{
2823
    struct target_modify_ldt_ldt_s ldt_info;
2824
    struct target_modify_ldt_ldt_s *target_ldt_info;
2825
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2826
    int seg_not_present, useable, lm;
2827
    uint32_t *lp, entry_1, entry_2;
2828

    
2829
    if (bytecount != sizeof(ldt_info))
2830
        return -TARGET_EINVAL;
2831
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2832
        return -TARGET_EFAULT;
2833
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2834
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2835
    ldt_info.limit = tswap32(target_ldt_info->limit);
2836
    ldt_info.flags = tswap32(target_ldt_info->flags);
2837
    unlock_user_struct(target_ldt_info, ptr, 0);
2838

    
2839
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2840
        return -TARGET_EINVAL;
2841
    seg_32bit = ldt_info.flags & 1;
2842
    contents = (ldt_info.flags >> 1) & 3;
2843
    read_exec_only = (ldt_info.flags >> 3) & 1;
2844
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2845
    seg_not_present = (ldt_info.flags >> 5) & 1;
2846
    useable = (ldt_info.flags >> 6) & 1;
2847
#ifdef TARGET_ABI32
2848
    lm = 0;
2849
#else
2850
    lm = (ldt_info.flags >> 7) & 1;
2851
#endif
2852
    if (contents == 3) {
2853
        if (oldmode)
2854
            return -TARGET_EINVAL;
2855
        if (seg_not_present == 0)
2856
            return -TARGET_EINVAL;
2857
    }
2858
    /* allocate the LDT */
2859
    if (!ldt_table) {
2860
        env->ldt.base = target_mmap(0,
2861
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2862
                                    PROT_READ|PROT_WRITE,
2863
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2864
        if (env->ldt.base == -1)
2865
            return -TARGET_ENOMEM;
2866
        memset(g2h(env->ldt.base), 0,
2867
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2868
        env->ldt.limit = 0xffff;
2869
        ldt_table = g2h(env->ldt.base);
2870
    }
2871

    
2872
    /* NOTE: same code as Linux kernel */
2873
    /* Allow LDTs to be cleared by the user. */
2874
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2875
        if (oldmode ||
2876
            (contents == 0                &&
2877
             read_exec_only == 1        &&
2878
             seg_32bit == 0                &&
2879
             limit_in_pages == 0        &&
2880
             seg_not_present == 1        &&
2881
             useable == 0 )) {
2882
            entry_1 = 0;
2883
            entry_2 = 0;
2884
            goto install;
2885
        }
2886
    }
2887

    
2888
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2889
        (ldt_info.limit & 0x0ffff);
2890
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2891
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2892
        (ldt_info.limit & 0xf0000) |
2893
        ((read_exec_only ^ 1) << 9) |
2894
        (contents << 10) |
2895
        ((seg_not_present ^ 1) << 15) |
2896
        (seg_32bit << 22) |
2897
        (limit_in_pages << 23) |
2898
        (lm << 21) |
2899
        0x7000;
2900
    if (!oldmode)
2901
        entry_2 |= (useable << 20);
2902

    
2903
    /* Install the new entry ...  */
2904
install:
2905
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2906
    lp[0] = tswap32(entry_1);
2907
    lp[1] = tswap32(entry_2);
2908
    return 0;
2909
}
2910

    
2911
/* specific and weird i386 syscalls */
2912
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2913
                              unsigned long bytecount)
2914
{
2915
    abi_long ret;
2916

    
2917
    switch (func) {
2918
    case 0:
2919
        ret = read_ldt(ptr, bytecount);
2920
        break;
2921
    case 1:
2922
        ret = write_ldt(env, ptr, bytecount, 1);
2923
        break;
2924
    case 0x11:
2925
        ret = write_ldt(env, ptr, bytecount, 0);
2926
        break;
2927
    default:
2928
        ret = -TARGET_ENOSYS;
2929
        break;
2930
    }
2931
    return ret;
2932
}
2933

    
2934
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2935
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2936
{
2937
    uint64_t *gdt_table = g2h(env->gdt.base);
2938
    struct target_modify_ldt_ldt_s ldt_info;
2939
    struct target_modify_ldt_ldt_s *target_ldt_info;
2940
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2941
    int seg_not_present, useable, lm;
2942
    uint32_t *lp, entry_1, entry_2;
2943
    int i;
2944

    
2945
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2946
    if (!target_ldt_info)
2947
        return -TARGET_EFAULT;
2948
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2949
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2950
    ldt_info.limit = tswap32(target_ldt_info->limit);
2951
    ldt_info.flags = tswap32(target_ldt_info->flags);
2952
    if (ldt_info.entry_number == -1) {
2953
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2954
            if (gdt_table[i] == 0) {
2955
                ldt_info.entry_number = i;
2956
                target_ldt_info->entry_number = tswap32(i);
2957
                break;
2958
            }
2959
        }
2960
    }
2961
    unlock_user_struct(target_ldt_info, ptr, 1);
2962

    
2963
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2964
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2965
           return -TARGET_EINVAL;
2966
    seg_32bit = ldt_info.flags & 1;
2967
    contents = (ldt_info.flags >> 1) & 3;
2968
    read_exec_only = (ldt_info.flags >> 3) & 1;
2969
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2970
    seg_not_present = (ldt_info.flags >> 5) & 1;
2971
    useable = (ldt_info.flags >> 6) & 1;
2972
#ifdef TARGET_ABI32
2973
    lm = 0;
2974
#else
2975
    lm = (ldt_info.flags >> 7) & 1;
2976
#endif
2977

    
2978
    if (contents == 3) {
2979
        if (seg_not_present == 0)
2980
            return -TARGET_EINVAL;
2981
    }
2982

    
2983
    /* NOTE: same code as Linux kernel */
2984
    /* Allow LDTs to be cleared by the user. */
2985
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2986
        if ((contents == 0             &&
2987
             read_exec_only == 1       &&
2988
             seg_32bit == 0            &&
2989
             limit_in_pages == 0       &&
2990
             seg_not_present == 1      &&
2991
             useable == 0 )) {
2992
            entry_1 = 0;
2993
            entry_2 = 0;
2994
            goto install;
2995
        }
2996
    }
2997

    
2998
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2999
        (ldt_info.limit & 0x0ffff);
3000
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3001
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3002
        (ldt_info.limit & 0xf0000) |
3003
        ((read_exec_only ^ 1) << 9) |
3004
        (contents << 10) |
3005
        ((seg_not_present ^ 1) << 15) |
3006
        (seg_32bit << 22) |
3007
        (limit_in_pages << 23) |
3008
        (useable << 20) |
3009
        (lm << 21) |
3010
        0x7000;
3011

    
3012
    /* Install the new entry ...  */
3013
install:
3014
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3015
    lp[0] = tswap32(entry_1);
3016
    lp[1] = tswap32(entry_2);
3017
    return 0;
3018
}
3019

    
3020
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3021
{
3022
    struct target_modify_ldt_ldt_s *target_ldt_info;
3023
    uint64_t *gdt_table = g2h(env->gdt.base);
3024
    uint32_t base_addr, limit, flags;
3025
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3026
    int seg_not_present, useable, lm;
3027
    uint32_t *lp, entry_1, entry_2;
3028

    
3029
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3030
    if (!target_ldt_info)
3031
        return -TARGET_EFAULT;
3032
    idx = tswap32(target_ldt_info->entry_number);
3033
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3034
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3035
        unlock_user_struct(target_ldt_info, ptr, 1);
3036
        return -TARGET_EINVAL;
3037
    }
3038
    lp = (uint32_t *)(gdt_table + idx);
3039
    entry_1 = tswap32(lp[0]);
3040
    entry_2 = tswap32(lp[1]);
3041
    
3042
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3043
    contents = (entry_2 >> 10) & 3;
3044
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3045
    seg_32bit = (entry_2 >> 22) & 1;
3046
    limit_in_pages = (entry_2 >> 23) & 1;
3047
    useable = (entry_2 >> 20) & 1;
3048
#ifdef TARGET_ABI32
3049
    lm = 0;
3050
#else
3051
    lm = (entry_2 >> 21) & 1;
3052
#endif
3053
    flags = (seg_32bit << 0) | (contents << 1) |
3054
        (read_exec_only << 3) | (limit_in_pages << 4) |
3055
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3056
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3057
    base_addr = (entry_1 >> 16) | 
3058
        (entry_2 & 0xff000000) | 
3059
        ((entry_2 & 0xff) << 16);
3060
    target_ldt_info->base_addr = tswapl(base_addr);
3061
    target_ldt_info->limit = tswap32(limit);
3062
    target_ldt_info->flags = tswap32(flags);
3063
    unlock_user_struct(target_ldt_info, ptr, 1);
3064
    return 0;
3065
}
3066
#endif /* TARGET_I386 && TARGET_ABI32 */
3067

    
3068
#ifndef TARGET_ABI32
3069
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3070
{
3071
    abi_long ret;
3072
    abi_ulong val;
3073
    int idx;
3074
    
3075
    switch(code) {
3076
    case TARGET_ARCH_SET_GS:
3077
    case TARGET_ARCH_SET_FS:
3078
        if (code == TARGET_ARCH_SET_GS)
3079
            idx = R_GS;
3080
        else
3081
            idx = R_FS;
3082
        cpu_x86_load_seg(env, idx, 0);
3083
        env->segs[idx].base = addr;
3084
        break;
3085
    case TARGET_ARCH_GET_GS:
3086
    case TARGET_ARCH_GET_FS:
3087
        if (code == TARGET_ARCH_GET_GS)
3088
            idx = R_GS;
3089
        else
3090
            idx = R_FS;
3091
        val = env->segs[idx].base;
3092
        if (put_user(val, addr, abi_ulong))
3093
            return -TARGET_EFAULT;
3094
        break;
3095
    default:
3096
        ret = -TARGET_EINVAL;
3097
        break;
3098
    }
3099
    return 0;
3100
}
3101
#endif
3102

    
3103
#endif /* defined(TARGET_I386) */
3104

    
3105
#if defined(USE_NPTL)
3106

    
3107
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3108

    
3109
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3110
typedef struct {
3111
    CPUState *env;
3112
    pthread_mutex_t mutex;
3113
    pthread_cond_t cond;
3114
    pthread_t thread;
3115
    uint32_t tid;
3116
    abi_ulong child_tidptr;
3117
    abi_ulong parent_tidptr;
3118
    sigset_t sigmask;
3119
} new_thread_info;
3120

    
3121
static void *clone_func(void *arg)
3122
{
3123
    new_thread_info *info = arg;
3124
    CPUState *env;
3125

    
3126
    env = info->env;
3127
    thread_env = env;
3128
    info->tid = gettid();
3129
    if (info->child_tidptr)
3130
        put_user_u32(info->tid, info->child_tidptr);
3131
    if (info->parent_tidptr)
3132
        put_user_u32(info->tid, info->parent_tidptr);
3133
    /* Enable signals.  */
3134
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3135
    /* Signal to the parent that we're ready.  */
3136
    pthread_mutex_lock(&info->mutex);
3137
    pthread_cond_broadcast(&info->cond);
3138
    pthread_mutex_unlock(&info->mutex);
3139
    /* Wait until the parent has finshed initializing the tls state.  */
3140
    pthread_mutex_lock(&clone_lock);
3141
    pthread_mutex_unlock(&clone_lock);
3142
    cpu_loop(env);
3143
    /* never exits */
3144
    return NULL;
3145
}
3146
#else
3147
/* this stack is the equivalent of the kernel stack associated with a
3148
   thread/process */
3149
#define NEW_STACK_SIZE 8192
3150

    
3151
static int clone_func(void *arg)
3152
{
3153
    CPUState *env = arg;
3154
    cpu_loop(env);
3155
    /* never exits */
3156
    return 0;
3157
}
3158
#endif
3159

    
3160
/* do_fork() Must return host values and target errnos (unlike most
3161
   do_*() functions). */
3162
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3163
                   abi_ulong parent_tidptr, target_ulong newtls,
3164
                   abi_ulong child_tidptr)
3165
{
3166
    int ret;
3167
    TaskState *ts;
3168
    uint8_t *new_stack;
3169
    CPUState *new_env;
3170
#if defined(USE_NPTL)
3171
    unsigned int nptl_flags;
3172
    sigset_t sigmask;
3173
#endif
3174

    
3175
    /* Emulate vfork() with fork() */
3176
    if (flags & CLONE_VFORK)
3177
        flags &= ~(CLONE_VFORK | CLONE_VM);
3178

    
3179
    if (flags & CLONE_VM) {
3180
#if defined(USE_NPTL)
3181
        new_thread_info info;
3182
        pthread_attr_t attr;
3183
#endif
3184
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3185
        init_task_state(ts);
3186
        new_stack = ts->stack;
3187
        /* we create a new CPU instance. */
3188
        new_env = cpu_copy(env);
3189
        /* Init regs that differ from the parent.  */
3190
        cpu_clone_regs(new_env, newsp);
3191
        new_env->opaque = ts;
3192
#if defined(USE_NPTL)
3193
        nptl_flags = flags;
3194
        flags &= ~CLONE_NPTL_FLAGS2;
3195

    
3196
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3197
            ts->child_tidptr = child_tidptr;
3198
        }
3199

    
3200
        if (nptl_flags & CLONE_SETTLS)
3201
            cpu_set_tls (new_env, newtls);
3202

    
3203
        /* Grab a mutex so that thread setup appears atomic.  */
3204
        pthread_mutex_lock(&clone_lock);
3205

    
3206
        memset(&info, 0, sizeof(info));
3207
        pthread_mutex_init(&info.mutex, NULL);
3208
        pthread_mutex_lock(&info.mutex);
3209
        pthread_cond_init(&info.cond, NULL);
3210
        info.env = new_env;
3211
        if (nptl_flags & CLONE_CHILD_SETTID)
3212
            info.child_tidptr = child_tidptr;
3213
        if (nptl_flags & CLONE_PARENT_SETTID)
3214
            info.parent_tidptr = parent_tidptr;
3215

    
3216
        ret = pthread_attr_init(&attr);
3217
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3218
        /* It is not safe to deliver signals until the child has finished
3219
           initializing, so temporarily block all signals.  */
3220
        sigfillset(&sigmask);
3221
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3222

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

    
3226
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3227
        pthread_attr_destroy(&attr);
3228
        if (ret == 0) {
3229
            /* Wait for the child to initialize.  */
3230
            pthread_cond_wait(&info.cond, &info.mutex);
3231
            ret = info.tid;
3232
            if (flags & CLONE_PARENT_SETTID)
3233
                put_user_u32(ret, parent_tidptr);
3234
        } else {
3235
            ret = -1;
3236
        }
3237
        pthread_mutex_unlock(&info.mutex);
3238
        pthread_cond_destroy(&info.cond);
3239
        pthread_mutex_destroy(&info.mutex);
3240
        pthread_mutex_unlock(&clone_lock);
3241
#else
3242
        if (flags & CLONE_NPTL_FLAGS2)
3243
            return -EINVAL;
3244
        /* This is probably going to die very quickly, but do it anyway.  */
3245
#ifdef __ia64__
3246
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3247
#else
3248
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3249
#endif
3250
#endif
3251
    } else {
3252
        /* if no CLONE_VM, we consider it is a fork */
3253
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3254
            return -EINVAL;
3255
        fork_start();
3256
        ret = fork();
3257
        if (ret == 0) {
3258
            /* Child Process.  */
3259
            cpu_clone_regs(env, newsp);
3260
            fork_end(1);
3261
#if defined(USE_NPTL)
3262
            /* There is a race condition here.  The parent process could
3263
               theoretically read the TID in the child process before the child
3264
               tid is set.  This would require using either ptrace
3265
               (not implemented) or having *_tidptr to point at a shared memory
3266
               mapping.  We can't repeat the spinlock hack used above because
3267
               the child process gets its own copy of the lock.  */
3268
            if (flags & CLONE_CHILD_SETTID)
3269
                put_user_u32(gettid(), child_tidptr);
3270
            if (flags & CLONE_PARENT_SETTID)
3271
                put_user_u32(gettid(), parent_tidptr);
3272
            ts = (TaskState *)env->opaque;
3273
            if (flags & CLONE_SETTLS)
3274
                cpu_set_tls (env, newtls);
3275
            if (flags & CLONE_CHILD_CLEARTID)
3276
                ts->child_tidptr = child_tidptr;
3277
#endif
3278
        } else {
3279
            fork_end(0);
3280
        }
3281
    }
3282
    return ret;
3283
}
3284

    
3285
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3286
{
3287
    struct flock fl;
3288
    struct target_flock *target_fl;
3289
    struct flock64 fl64;
3290
    struct target_flock64 *target_fl64;
3291
    abi_long ret;
3292

    
3293
    switch(cmd) {
3294
    case TARGET_F_GETLK:
3295
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3296
            return -TARGET_EFAULT;
3297
        fl.l_type = tswap16(target_fl->l_type);
3298
        fl.l_whence = tswap16(target_fl->l_whence);
3299
        fl.l_start = tswapl(target_fl->l_start);
3300
        fl.l_len = tswapl(target_fl->l_len);
3301
        fl.l_pid = tswapl(target_fl->l_pid);
3302
        unlock_user_struct(target_fl, arg, 0);
3303
        ret = get_errno(fcntl(fd, cmd, &fl));
3304
        if (ret == 0) {
3305
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3306
                return -TARGET_EFAULT;
3307
            target_fl->l_type = tswap16(fl.l_type);
3308
            target_fl->l_whence = tswap16(fl.l_whence);
3309
            target_fl->l_start = tswapl(fl.l_start);
3310
            target_fl->l_len = tswapl(fl.l_len);
3311
            target_fl->l_pid = tswapl(fl.l_pid);
3312
            unlock_user_struct(target_fl, arg, 1);
3313
        }
3314
        break;
3315

    
3316
    case TARGET_F_SETLK:
3317
    case TARGET_F_SETLKW:
3318
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3319
            return -TARGET_EFAULT;
3320
        fl.l_type = tswap16(target_fl->l_type);
3321
        fl.l_whence = tswap16(target_fl->l_whence);
3322
        fl.l_start = tswapl(target_fl->l_start);
3323
        fl.l_len = tswapl(target_fl->l_len);
3324
        fl.l_pid = tswapl(target_fl->l_pid);
3325
        unlock_user_struct(target_fl, arg, 0);
3326
        ret = get_errno(fcntl(fd, cmd, &fl));
3327
        break;
3328

    
3329
    case TARGET_F_GETLK64:
3330
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3331
            return -TARGET_EFAULT;
3332
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3333
        fl64.l_whence = tswap16(target_fl64->l_whence);
3334
        fl64.l_start = tswapl(target_fl64->l_start);
3335
        fl64.l_len = tswapl(target_fl64->l_len);
3336
        fl64.l_pid = tswap16(target_fl64->l_pid);
3337
        unlock_user_struct(target_fl64, arg, 0);
3338
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3339
        if (ret == 0) {
3340
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3341
                return -TARGET_EFAULT;
3342
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3343
            target_fl64->l_whence = tswap16(fl64.l_whence);
3344
            target_fl64->l_start = tswapl(fl64.l_start);
3345
            target_fl64->l_len = tswapl(fl64.l_len);
3346
            target_fl64->l_pid = tswapl(fl64.l_pid);
3347
            unlock_user_struct(target_fl64, arg, 1);
3348
        }
3349
        break;
3350
    case TARGET_F_SETLK64:
3351
    case TARGET_F_SETLKW64:
3352
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3353
            return -TARGET_EFAULT;
3354
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3355
        fl64.l_whence = tswap16(target_fl64->l_whence);
3356
        fl64.l_start = tswapl(target_fl64->l_start);
3357
        fl64.l_len = tswapl(target_fl64->l_len);
3358
        fl64.l_pid = tswap16(target_fl64->l_pid);
3359
        unlock_user_struct(target_fl64, arg, 0);
3360
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3361
        break;
3362

    
3363
    case F_GETFL:
3364
        ret = get_errno(fcntl(fd, cmd, arg));
3365
        if (ret >= 0) {
3366
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3367
        }
3368
        break;
3369

    
3370
    case F_SETFL:
3371
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3372
        break;
3373

    
3374
    default:
3375
        ret = get_errno(fcntl(fd, cmd, arg));
3376
        break;
3377
    }
3378
    return ret;
3379
}
3380

    
3381
#ifdef USE_UID16
3382

    
3383
static inline int high2lowuid(int uid)
3384
{
3385
    if (uid > 65535)
3386
        return 65534;
3387
    else
3388
        return uid;
3389
}
3390

    
3391
static inline int high2lowgid(int gid)
3392
{
3393
    if (gid > 65535)
3394
        return 65534;
3395
    else
3396
        return gid;
3397
}
3398

    
3399
static inline int low2highuid(int uid)
3400
{
3401
    if ((int16_t)uid == -1)
3402
        return -1;
3403
    else
3404
        return uid;
3405
}
3406

    
3407
static inline int low2highgid(int gid)
3408
{
3409
    if ((int16_t)gid == -1)
3410
        return -1;
3411
    else
3412
        return gid;
3413
}
3414

    
3415
#endif /* USE_UID16 */
3416

    
3417
void syscall_init(void)
3418
{
3419
    IOCTLEntry *ie;
3420
    const argtype *arg_type;
3421
    int size;
3422
    int i;
3423

    
3424
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3425
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3426
#include "syscall_types.h"
3427
#undef STRUCT
3428
#undef STRUCT_SPECIAL
3429

    
3430
    /* we patch the ioctl size if necessary. We rely on the fact that
3431
       no ioctl has all the bits at '1' in the size field */
3432
    ie = ioctl_entries;
3433
    while (ie->target_cmd != 0) {
3434
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3435
            TARGET_IOC_SIZEMASK) {
3436
            arg_type = ie->arg_type;
3437
            if (arg_type[0] != TYPE_PTR) {
3438
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3439
                        ie->target_cmd);
3440
                exit(1);
3441
            }
3442
            arg_type++;
3443
            size = thunk_type_size(arg_type, 0);
3444
            ie->target_cmd = (ie->target_cmd &
3445
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3446
                (size << TARGET_IOC_SIZESHIFT);
3447
        }
3448

    
3449
        /* Build target_to_host_errno_table[] table from
3450
         * host_to_target_errno_table[]. */
3451
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3452
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3453

    
3454
        /* automatic consistency check if same arch */
3455
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3456
    (defined(__x86_64__) && defined(TARGET_X86_64))
3457
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3458
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3459
                    ie->name, ie->target_cmd, ie->host_cmd);
3460
        }
3461
#endif
3462
        ie++;
3463
    }
3464
}
3465

    
3466
#if TARGET_ABI_BITS == 32
3467
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3468
{
3469
#ifdef TARGET_WORDS_BIGENDIAN
3470
    return ((uint64_t)word0 << 32) | word1;
3471
#else
3472
    return ((uint64_t)word1 << 32) | word0;
3473
#endif
3474
}
3475
#else /* TARGET_ABI_BITS == 32 */
3476
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3477
{
3478
    return word0;
3479
}
3480
#endif /* TARGET_ABI_BITS != 32 */
3481

    
3482
#ifdef TARGET_NR_truncate64
3483
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3484
                                         abi_long arg2,
3485
                                         abi_long arg3,
3486
                                         abi_long arg4)
3487
{
3488
#ifdef TARGET_ARM
3489
    if (((CPUARMState *)cpu_env)->eabi)
3490
      {
3491
        arg2 = arg3;
3492
        arg3 = arg4;
3493
      }
3494
#endif
3495
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3496
}
3497
#endif
3498

    
3499
#ifdef TARGET_NR_ftruncate64
3500
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3501
                                          abi_long arg2,
3502
                                          abi_long arg3,
3503
                                          abi_long arg4)
3504
{
3505
#ifdef TARGET_ARM
3506
    if (((CPUARMState *)cpu_env)->eabi)
3507
      {
3508
        arg2 = arg3;
3509
        arg3 = arg4;
3510
      }
3511
#endif
3512
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3513
}
3514
#endif
3515

    
3516
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3517
                                               abi_ulong target_addr)
3518
{
3519
    struct target_timespec *target_ts;
3520

    
3521
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3522
        return -TARGET_EFAULT;
3523
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3524
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3525
    unlock_user_struct(target_ts, target_addr, 0);
3526
    return 0;
3527
}
3528

    
3529
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3530
                                               struct timespec *host_ts)
3531
{
3532
    struct target_timespec *target_ts;
3533

    
3534
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3535
        return -TARGET_EFAULT;
3536
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3537
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3538
    unlock_user_struct(target_ts, target_addr, 1);
3539
    return 0;
3540
}
3541

    
3542
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3543
static inline abi_long host_to_target_stat64(void *cpu_env,
3544
                                             abi_ulong target_addr,
3545
                                             struct stat *host_st)
3546
{
3547
#ifdef TARGET_ARM
3548
    if (((CPUARMState *)cpu_env)->eabi) {
3549
        struct target_eabi_stat64 *target_st;
3550

    
3551
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3552
            return -TARGET_EFAULT;
3553
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3554
        __put_user(host_st->st_dev, &target_st->st_dev);
3555
        __put_user(host_st->st_ino, &target_st->st_ino);
3556
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3557
        __put_user(host_st->st_ino, &target_st->__st_ino);
3558
#endif
3559
        __put_user(host_st->st_mode, &target_st->st_mode);
3560
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3561
        __put_user(host_st->st_uid, &target_st->st_uid);
3562
        __put_user(host_st->st_gid, &target_st->st_gid);
3563
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3564
        __put_user(host_st->st_size, &target_st->st_size);
3565
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3566
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3567
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3568
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3569
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3570
        unlock_user_struct(target_st, target_addr, 1);
3571
    } else
3572
#endif
3573
    {
3574
#if TARGET_LONG_BITS == 64
3575
        struct target_stat *target_st;
3576
#else
3577
        struct target_stat64 *target_st;
3578
#endif
3579

    
3580
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3581
            return -TARGET_EFAULT;
3582
        memset(target_st, 0, sizeof(*target_st));
3583
        __put_user(host_st->st_dev, &target_st->st_dev);
3584
        __put_user(host_st->st_ino, &target_st->st_ino);
3585
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3586
        __put_user(host_st->st_ino, &target_st->__st_ino);
3587
#endif
3588
        __put_user(host_st->st_mode, &target_st->st_mode);
3589
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3590
        __put_user(host_st->st_uid, &target_st->st_uid);
3591
        __put_user(host_st->st_gid, &target_st->st_gid);
3592
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3593
        /* XXX: better use of kernel struct */
3594
        __put_user(host_st->st_size, &target_st->st_size);
3595
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3596
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3597
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3598
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3599
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3600
        unlock_user_struct(target_st, target_addr, 1);
3601
    }
3602

    
3603
    return 0;
3604
}
3605
#endif
3606

    
3607
#if defined(USE_NPTL)
3608
/* ??? Using host futex calls even when target atomic operations
3609
   are not really atomic probably breaks things.  However implementing
3610
   futexes locally would make futexes shared between multiple processes
3611
   tricky.  However they're probably useless because guest atomic
3612
   operations won't work either.  */
3613
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3614
                    target_ulong uaddr2, int val3)
3615
{
3616
    struct timespec ts, *pts;
3617

    
3618
    /* ??? We assume FUTEX_* constants are the same on both host
3619
       and target.  */
3620
    switch (op) {
3621
    case FUTEX_WAIT:
3622
        if (timeout) {
3623
            pts = &ts;
3624
            target_to_host_timespec(pts, timeout);
3625
        } else {
3626
            pts = NULL;
3627
        }
3628
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3629
                         pts, NULL, 0));
3630
    case FUTEX_WAKE:
3631
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3632
    case FUTEX_FD:
3633
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3634
    case FUTEX_REQUEUE:
3635
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3636
                         NULL, g2h(uaddr2), 0));
3637
    case FUTEX_CMP_REQUEUE:
3638
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3639
                         NULL, g2h(uaddr2), tswap32(val3)));
3640
    default:
3641
        return -TARGET_ENOSYS;
3642
    }
3643
}
3644
#endif
3645

    
3646
int get_osversion(void)
3647
{
3648
    static int osversion;
3649
    struct new_utsname buf;
3650
    const char *s;
3651
    int i, n, tmp;
3652
    if (osversion)
3653
        return osversion;
3654
    if (qemu_uname_release && *qemu_uname_release) {
3655
        s = qemu_uname_release;
3656
    } else {
3657
        if (sys_uname(&buf))
3658
            return 0;
3659
        s = buf.release;
3660
    }
3661
    tmp = 0;
3662
    for (i = 0; i < 3; i++) {
3663
        n = 0;
3664
        while (*s >= '0' && *s <= '9') {
3665
            n *= 10;
3666
            n += *s - '0';
3667
            s++;
3668
        }
3669
        tmp = (tmp << 8) + n;
3670
        if (*s == '.')
3671
            s++;
3672
    }
3673
    osversion = tmp;
3674
    return osversion;
3675
}
3676

    
3677
/* do_syscall() should always have a single exit point at the end so
3678
   that actions, such as logging of syscall results, can be performed.
3679
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3680
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3681
                    abi_long arg2, abi_long arg3, abi_long arg4,
3682
                    abi_long arg5, abi_long arg6)
3683
{
3684
    abi_long ret;
3685
    struct stat st;
3686
    struct statfs stfs;
3687
    void *p;
3688

    
3689
#ifdef DEBUG
3690
    gemu_log("syscall %d", num);
3691
#endif
3692
    if(do_strace)
3693
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3694

    
3695
    switch(num) {
3696
    case TARGET_NR_exit:
3697
#ifdef USE_NPTL
3698
      /* In old applications this may be used to implement _exit(2).
3699
         However in threaded applictions it is used for thread termination,
3700
         and _exit_group is used for application termination.
3701
         Do thread termination if we have more then one thread.  */
3702
      /* FIXME: This probably breaks if a signal arrives.  We should probably
3703
         be disabling signals.  */
3704
      if (first_cpu->next_cpu) {
3705
          CPUState **lastp;
3706
          CPUState *p;
3707

    
3708
          cpu_list_lock();
3709
          lastp = &first_cpu;
3710
          p = first_cpu;
3711
          while (p && p != (CPUState *)cpu_env) {
3712
              lastp = &p->next_cpu;
3713
              p = p->next_cpu;
3714
          }
3715
          /* If we didn't find the CPU for this thread then something is
3716
             horribly wrong.  */
3717
          if (!p)
3718
              abort();
3719
          /* Remove the CPU from the list.  */
3720
          *lastp = p->next_cpu;
3721
          cpu_list_unlock();
3722
          TaskState *ts = ((CPUState *)cpu_env)->opaque;
3723
          if (ts->child_tidptr) {
3724
              put_user_u32(0, ts->child_tidptr);
3725
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3726
                        NULL, NULL, 0);
3727
          }
3728
          /* TODO: Free CPU state.  */
3729
          pthread_exit(NULL);
3730
      }
3731
#endif
3732
#ifdef HAVE_GPROF
3733
        _mcleanup();
3734
#endif
3735
        gdb_exit(cpu_env, arg1);
3736
        _exit(arg1);
3737
        ret = 0; /* avoid warning */
3738
        break;
3739
    case TARGET_NR_read:
3740
        if (arg3 == 0)
3741
            ret = 0;
3742
        else {
3743
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3744
                goto efault;
3745
            ret = get_errno(read(arg1, p, arg3));
3746
            unlock_user(p, arg2, ret);
3747
        }
3748
        break;
3749
    case TARGET_NR_write:
3750
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3751
            goto efault;
3752
        ret = get_errno(write(arg1, p, arg3));
3753
        unlock_user(p, arg2, 0);
3754
        break;
3755
    case TARGET_NR_open:
3756
        if (!(p = lock_user_string(arg1)))
3757
            goto efault;
3758
        ret = get_errno(open(path(p),
3759
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3760
                             arg3));
3761
        unlock_user(p, arg1, 0);
3762
        break;
3763
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3764
    case TARGET_NR_openat:
3765
        if (!(p = lock_user_string(arg2)))
3766
            goto efault;
3767
        ret = get_errno(sys_openat(arg1,
3768
                                   path(p),
3769
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3770
                                   arg4));
3771
        unlock_user(p, arg2, 0);
3772
        break;
3773
#endif
3774
    case TARGET_NR_close:
3775
        ret = get_errno(close(arg1));
3776
        break;
3777
    case TARGET_NR_brk:
3778
        ret = do_brk(arg1);
3779
        break;
3780
    case TARGET_NR_fork:
3781
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3782
        break;
3783
#ifdef TARGET_NR_waitpid
3784
    case TARGET_NR_waitpid:
3785
        {
3786
            int status;
3787
            ret = get_errno(waitpid(arg1, &status, arg3));
3788
            if (!is_error(ret) && arg2
3789
                && put_user_s32(status, arg2))
3790
                goto efault;
3791
        }
3792
        break;
3793
#endif
3794
#ifdef TARGET_NR_waitid
3795
    case TARGET_NR_waitid:
3796
        {
3797
            siginfo_t info;
3798
            info.si_pid = 0;
3799
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3800
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3801
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3802
                    goto efault;
3803
                host_to_target_siginfo(p, &info);
3804
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3805
            }
3806
        }
3807
        break;
3808
#endif
3809
#ifdef TARGET_NR_creat /* not on alpha */
3810
    case TARGET_NR_creat:
3811
        if (!(p = lock_user_string(arg1)))
3812
            goto efault;
3813
        ret = get_errno(creat(p, arg2));
3814
        unlock_user(p, arg1, 0);
3815
        break;
3816
#endif
3817
    case TARGET_NR_link:
3818
        {
3819
            void * p2;
3820
            p = lock_user_string(arg1);
3821
            p2 = lock_user_string(arg2);
3822
            if (!p || !p2)
3823
                ret = -TARGET_EFAULT;
3824
            else
3825
                ret = get_errno(link(p, p2));
3826
            unlock_user(p2, arg2, 0);
3827
            unlock_user(p, arg1, 0);
3828
        }
3829
        break;
3830
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3831
    case TARGET_NR_linkat:
3832
        {
3833
            void * p2 = NULL;
3834
            if (!arg2 || !arg4)
3835
                goto efault;
3836
            p  = lock_user_string(arg2);
3837
            p2 = lock_user_string(arg4);
3838
            if (!p || !p2)
3839
                ret = -TARGET_EFAULT;
3840
            else
3841
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3842
            unlock_user(p, arg2, 0);
3843
            unlock_user(p2, arg4, 0);
3844
        }
3845
        break;
3846
#endif
3847
    case TARGET_NR_unlink:
3848
        if (!(p = lock_user_string(arg1)))
3849
            goto efault;
3850
        ret = get_errno(unlink(p));
3851
        unlock_user(p, arg1, 0);
3852
        break;
3853
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3854
    case TARGET_NR_unlinkat:
3855
        if (!(p = lock_user_string(arg2)))
3856
            goto efault;
3857
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3858
        unlock_user(p, arg2, 0);
3859
        break;
3860
#endif
3861
    case TARGET_NR_execve:
3862
        {
3863
            char **argp, **envp;
3864
            int argc, envc;
3865
            abi_ulong gp;
3866
            abi_ulong guest_argp;
3867
            abi_ulong guest_envp;
3868
            abi_ulong addr;
3869
            char **q;
3870

    
3871
            argc = 0;
3872
            guest_argp = arg2;
3873
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3874
                if (get_user_ual(addr, gp))
3875
                    goto efault;
3876
                if (!addr)
3877
                    break;
3878
                argc++;
3879
            }
3880
            envc = 0;
3881
            guest_envp = arg3;
3882
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3883
                if (get_user_ual(addr, gp))
3884
                    goto efault;
3885
                if (!addr)
3886
                    break;
3887
                envc++;
3888
            }
3889

    
3890
            argp = alloca((argc + 1) * sizeof(void *));
3891
            envp = alloca((envc + 1) * sizeof(void *));
3892

    
3893
            for (gp = guest_argp, q = argp; gp;
3894
                  gp += sizeof(abi_ulong), q++) {
3895
                if (get_user_ual(addr, gp))
3896
                    goto execve_efault;
3897
                if (!addr)
3898
                    break;
3899
                if (!(*q = lock_user_string(addr)))
3900
                    goto execve_efault;
3901
            }
3902
            *q = NULL;
3903

    
3904
            for (gp = guest_envp, q = envp; gp;
3905
                  gp += sizeof(abi_ulong), q++) {
3906
                if (get_user_ual(addr, gp))
3907
                    goto execve_efault;
3908
                if (!addr)
3909
                    break;
3910
                if (!(*q = lock_user_string(addr)))
3911
                    goto execve_efault;
3912
            }
3913
            *q = NULL;
3914

    
3915
            if (!(p = lock_user_string(arg1)))
3916
                goto execve_efault;
3917
            ret = get_errno(execve(p, argp, envp));
3918
            unlock_user(p, arg1, 0);
3919

    
3920
            goto execve_end;
3921

    
3922
        execve_efault:
3923
            ret = -TARGET_EFAULT;
3924

    
3925
        execve_end:
3926
            for (gp = guest_argp, q = argp; *q;
3927
                  gp += sizeof(abi_ulong), q++) {
3928
                if (get_user_ual(addr, gp)
3929
                    || !addr)
3930
                    break;
3931
                unlock_user(*q, addr, 0);
3932
            }
3933
            for (gp = guest_envp, q = envp; *q;
3934
                  gp += sizeof(abi_ulong), q++) {
3935
                if (get_user_ual(addr, gp)
3936
                    || !addr)
3937
                    break;
3938
                unlock_user(*q, addr, 0);
3939
            }
3940
        }
3941
        break;
3942
    case TARGET_NR_chdir:
3943
        if (!(p = lock_user_string(arg1)))
3944
            goto efault;
3945
        ret = get_errno(chdir(p));
3946
        unlock_user(p, arg1, 0);
3947
        break;
3948
#ifdef TARGET_NR_time
3949
    case TARGET_NR_time:
3950
        {
3951
            time_t host_time;
3952
            ret = get_errno(time(&host_time));
3953
            if (!is_error(ret)
3954
                && arg1
3955
                && put_user_sal(host_time, arg1))
3956
                goto efault;
3957
        }
3958
        break;
3959
#endif
3960
    case TARGET_NR_mknod:
3961
        if (!(p = lock_user_string(arg1)))
3962
            goto efault;
3963
        ret = get_errno(mknod(p, arg2, arg3));
3964
        unlock_user(p, arg1, 0);
3965
        break;
3966
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3967
    case TARGET_NR_mknodat:
3968
        if (!(p = lock_user_string(arg2)))
3969
            goto efault;
3970
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3971
        unlock_user(p, arg2, 0);
3972
        break;
3973
#endif
3974
    case TARGET_NR_chmod:
3975
        if (!(p = lock_user_string(arg1)))
3976
            goto efault;
3977
        ret = get_errno(chmod(p, arg2));
3978
        unlock_user(p, arg1, 0);
3979
        break;
3980
#ifdef TARGET_NR_break
3981
    case TARGET_NR_break:
3982
        goto unimplemented;
3983
#endif
3984
#ifdef TARGET_NR_oldstat
3985
    case TARGET_NR_oldstat:
3986
        goto unimplemented;
3987
#endif
3988
    case TARGET_NR_lseek:
3989
        ret = get_errno(lseek(arg1, arg2, arg3));
3990
        break;
3991
#ifdef TARGET_NR_getxpid
3992
    case TARGET_NR_getxpid:
3993
#else
3994
    case TARGET_NR_getpid:
3995
#endif
3996
        ret = get_errno(getpid());
3997
        break;
3998
    case TARGET_NR_mount:
3999
                {
4000
                        /* need to look at the data field */
4001
                        void *p2, *p3;
4002
                        p = lock_user_string(arg1);
4003
                        p2 = lock_user_string(arg2);
4004
                        p3 = lock_user_string(arg3);
4005
                        if (!p || !p2 || !p3)
4006
                            ret = -TARGET_EFAULT;
4007
                        else
4008
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4009
                             * do that since it's not guaranteed to be a NULL-terminated
4010
                             * string.
4011
                             */
4012
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4013
                        unlock_user(p, arg1, 0);
4014
                        unlock_user(p2, arg2, 0);
4015
                        unlock_user(p3, arg3, 0);
4016
                        break;
4017
                }
4018
#ifdef TARGET_NR_umount
4019
    case TARGET_NR_umount:
4020
        if (!(p = lock_user_string(arg1)))
4021
            goto efault;
4022
        ret = get_errno(umount(p));
4023
        unlock_user(p, arg1, 0);
4024
        break;
4025
#endif
4026
#ifdef TARGET_NR_stime /* not on alpha */
4027
    case TARGET_NR_stime:
4028
        {
4029
            time_t host_time;
4030
            if (get_user_sal(host_time, arg1))
4031
                goto efault;
4032
            ret = get_errno(stime(&host_time));
4033
        }
4034
        break;
4035
#endif
4036
    case TARGET_NR_ptrace:
4037
        goto unimplemented;
4038
#ifdef TARGET_NR_alarm /* not on alpha */
4039
    case TARGET_NR_alarm:
4040
        ret = alarm(arg1);
4041
        break;
4042
#endif
4043
#ifdef TARGET_NR_oldfstat
4044
    case TARGET_NR_oldfstat:
4045
        goto unimplemented;
4046
#endif
4047
#ifdef TARGET_NR_pause /* not on alpha */
4048
    case TARGET_NR_pause:
4049
        ret = get_errno(pause());
4050
        break;
4051
#endif
4052
#ifdef TARGET_NR_utime
4053
    case TARGET_NR_utime:
4054
        {
4055
            struct utimbuf tbuf, *host_tbuf;
4056
            struct target_utimbuf *target_tbuf;
4057
            if (arg2) {
4058
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4059
                    goto efault;
4060
                tbuf.actime = tswapl(target_tbuf->actime);
4061
                tbuf.modtime = tswapl(target_tbuf->modtime);
4062
                unlock_user_struct(target_tbuf, arg2, 0);
4063
                host_tbuf = &tbuf;
4064
            } else {
4065
                host_tbuf = NULL;
4066
            }
4067
            if (!(p = lock_user_string(arg1)))
4068
                goto efault;
4069
            ret = get_errno(utime(p, host_tbuf));
4070
            unlock_user(p, arg1, 0);
4071
        }
4072
        break;
4073
#endif
4074
    case TARGET_NR_utimes:
4075
        {
4076
            struct timeval *tvp, tv[2];
4077
            if (arg2) {
4078
                if (copy_from_user_timeval(&tv[0], arg2)
4079
                    || copy_from_user_timeval(&tv[1],
4080
                                              arg2 + sizeof(struct target_timeval)))
4081
                    goto efault;
4082
                tvp = tv;
4083
            } else {
4084
                tvp = NULL;
4085
            }
4086
            if (!(p = lock_user_string(arg1)))
4087
                goto efault;
4088
            ret = get_errno(utimes(p, tvp));
4089
            unlock_user(p, arg1, 0);
4090
        }
4091
        break;
4092
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4093
    case TARGET_NR_futimesat:
4094
        {
4095
            struct timeval *tvp, tv[2];
4096
            if (arg3) {
4097
                if (copy_from_user_timeval(&tv[0], arg3)
4098
                    || copy_from_user_timeval(&tv[1],
4099
                                              arg3 + sizeof(struct target_timeval)))
4100
                    goto efault;
4101
                tvp = tv;
4102
            } else {
4103
                tvp = NULL;
4104
            }
4105
            if (!(p = lock_user_string(arg2)))
4106
                goto efault;
4107
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4108
            unlock_user(p, arg2, 0);
4109
        }
4110
        break;
4111
#endif
4112
#ifdef TARGET_NR_stty
4113
    case TARGET_NR_stty:
4114
        goto unimplemented;
4115
#endif
4116
#ifdef TARGET_NR_gtty
4117
    case TARGET_NR_gtty:
4118
        goto unimplemented;
4119
#endif
4120
    case TARGET_NR_access:
4121
        if (!(p = lock_user_string(arg1)))
4122
            goto efault;
4123
        ret = get_errno(access(p, arg2));
4124
        unlock_user(p, arg1, 0);
4125
        break;
4126
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4127
    case TARGET_NR_faccessat:
4128
        if (!(p = lock_user_string(arg2)))
4129
            goto efault;
4130
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
4131
        unlock_user(p, arg2, 0);
4132
        break;
4133
#endif
4134
#ifdef TARGET_NR_nice /* not on alpha */
4135
    case TARGET_NR_nice:
4136
        ret = get_errno(nice(arg1));
4137
        break;
4138
#endif
4139
#ifdef TARGET_NR_ftime
4140
    case TARGET_NR_ftime:
4141
        goto unimplemented;
4142
#endif
4143
    case TARGET_NR_sync:
4144
        sync();
4145
        ret = 0;
4146
        break;
4147
    case TARGET_NR_kill:
4148
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4149
        break;
4150
    case TARGET_NR_rename:
4151
        {
4152
            void *p2;
4153
            p = lock_user_string(arg1);
4154
            p2 = lock_user_string(arg2);
4155
            if (!p || !p2)
4156
                ret = -TARGET_EFAULT;
4157
            else
4158
                ret = get_errno(rename(p, p2));
4159
            unlock_user(p2, arg2, 0);
4160
            unlock_user(p, arg1, 0);
4161
        }
4162
        break;
4163
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4164
    case TARGET_NR_renameat:
4165
        {
4166
            void *p2;
4167
            p  = lock_user_string(arg2);
4168
            p2 = lock_user_string(arg4);
4169
            if (!p || !p2)
4170
                ret = -TARGET_EFAULT;
4171
            else
4172
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4173
            unlock_user(p2, arg4, 0);
4174
            unlock_user(p, arg2, 0);
4175
        }
4176
        break;
4177
#endif
4178
    case TARGET_NR_mkdir:
4179
        if (!(p = lock_user_string(arg1)))
4180
            goto efault;
4181
        ret = get_errno(mkdir(p, arg2));
4182
        unlock_user(p, arg1, 0);
4183
        break;
4184
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4185
    case TARGET_NR_mkdirat:
4186
        if (!(p = lock_user_string(arg2)))
4187
            goto efault;
4188
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4189
        unlock_user(p, arg2, 0);
4190
        break;
4191
#endif
4192
    case TARGET_NR_rmdir:
4193
        if (!(p = lock_user_string(arg1)))
4194
            goto efault;
4195
        ret = get_errno(rmdir(p));
4196
        unlock_user(p, arg1, 0);
4197
        break;
4198
    case TARGET_NR_dup:
4199
        ret = get_errno(dup(arg1));
4200
        break;
4201
    case TARGET_NR_pipe:
4202
        {
4203
            int host_pipe[2];
4204
            ret = get_errno(pipe(host_pipe));
4205
            if (!is_error(ret)) {
4206
#if defined(TARGET_MIPS)
4207
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4208
                env->active_tc.gpr[3] = host_pipe[1];
4209
                ret = host_pipe[0];
4210
#elif defined(TARGET_SH4)
4211
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4212
                ret = host_pipe[0];
4213
#else
4214
                if (put_user_s32(host_pipe[0], arg1)
4215
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4216
                    goto efault;
4217
#endif
4218
            }
4219
        }
4220
        break;
4221
    case TARGET_NR_times:
4222
        {
4223
            struct target_tms *tmsp;
4224
            struct tms tms;
4225
            ret = get_errno(times(&tms));
4226
            if (arg1) {
4227
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4228
                if (!tmsp)
4229
                    goto efault;
4230
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4231
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4232
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4233
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4234
            }
4235
            if (!is_error(ret))
4236
                ret = host_to_target_clock_t(ret);
4237
        }
4238
        break;
4239
#ifdef TARGET_NR_prof
4240
    case TARGET_NR_prof:
4241
        goto unimplemented;
4242
#endif
4243
#ifdef TARGET_NR_signal
4244
    case TARGET_NR_signal:
4245
        goto unimplemented;
4246
#endif
4247
    case TARGET_NR_acct:
4248
        if (arg1 == 0) {
4249
            ret = get_errno(acct(NULL));
4250
        } else {
4251
            if (!(p = lock_user_string(arg1)))
4252
                goto efault;
4253
            ret = get_errno(acct(path(p)));
4254
            unlock_user(p, arg1, 0);
4255
        }
4256
        break;
4257
#ifdef TARGET_NR_umount2 /* not on alpha */
4258
    case TARGET_NR_umount2:
4259
        if (!(p = lock_user_string(arg1)))
4260
            goto efault;
4261
        ret = get_errno(umount2(p, arg2));
4262
        unlock_user(p, arg1, 0);
4263
        break;
4264
#endif
4265
#ifdef TARGET_NR_lock
4266
    case TARGET_NR_lock:
4267
        goto unimplemented;
4268
#endif
4269
    case TARGET_NR_ioctl:
4270
        ret = do_ioctl(arg1, arg2, arg3);
4271
        break;
4272
    case TARGET_NR_fcntl:
4273
        ret = do_fcntl(arg1, arg2, arg3);
4274
        break;
4275
#ifdef TARGET_NR_mpx
4276
    case TARGET_NR_mpx:
4277
        goto unimplemented;
4278
#endif
4279
    case TARGET_NR_setpgid:
4280
        ret = get_errno(setpgid(arg1, arg2));
4281
        break;
4282
#ifdef TARGET_NR_ulimit
4283
    case TARGET_NR_ulimit:
4284
        goto unimplemented;
4285
#endif
4286
#ifdef TARGET_NR_oldolduname
4287
    case TARGET_NR_oldolduname:
4288
        goto unimplemented;
4289
#endif
4290
    case TARGET_NR_umask:
4291
        ret = get_errno(umask(arg1));
4292
        break;
4293
    case TARGET_NR_chroot:
4294
        if (!(p = lock_user_string(arg1)))
4295
            goto efault;
4296
        ret = get_errno(chroot(p));
4297
        unlock_user(p, arg1, 0);
4298
        break;
4299
    case TARGET_NR_ustat:
4300
        goto unimplemented;
4301
    case TARGET_NR_dup2:
4302
        ret = get_errno(dup2(arg1, arg2));
4303
        break;
4304
#ifdef TARGET_NR_getppid /* not on alpha */
4305
    case TARGET_NR_getppid:
4306
        ret = get_errno(getppid());
4307
        break;
4308
#endif
4309
    case TARGET_NR_getpgrp:
4310
        ret = get_errno(getpgrp());
4311
        break;
4312
    case TARGET_NR_setsid:
4313
        ret = get_errno(setsid());
4314
        break;
4315
#ifdef TARGET_NR_sigaction
4316
    case TARGET_NR_sigaction:
4317
        {
4318
#if !defined(TARGET_MIPS)
4319
            struct target_old_sigaction *old_act;
4320
            struct target_sigaction act, oact, *pact;
4321
            if (arg2) {
4322
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4323
                    goto efault;
4324
                act._sa_handler = old_act->_sa_handler;
4325
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4326
                act.sa_flags = old_act->sa_flags;
4327
                act.sa_restorer = old_act->sa_restorer;
4328
                unlock_user_struct(old_act, arg2, 0);
4329
                pact = &act;
4330
            } else {
4331
                pact = NULL;
4332
            }
4333
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4334
            if (!is_error(ret) && arg3) {
4335
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4336
                    goto efault;
4337
                old_act->_sa_handler = oact._sa_handler;
4338
                old_act->sa_mask = oact.sa_mask.sig[0];
4339
                old_act->sa_flags = oact.sa_flags;
4340
                old_act->sa_restorer = oact.sa_restorer;
4341
                unlock_user_struct(old_act, arg3, 1);
4342
            }
4343
#else
4344
            struct target_sigaction act, oact, *pact, *old_act;
4345

    
4346
            if (arg2) {
4347
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4348
                    goto efault;
4349
                act._sa_handler = old_act->_sa_handler;
4350
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4351
                act.sa_flags = old_act->sa_flags;
4352
                unlock_user_struct(old_act, arg2, 0);
4353
                pact = &act;
4354
            } else {
4355
                pact = NULL;
4356
            }
4357

    
4358
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4359

    
4360
            if (!is_error(ret) && arg3) {
4361
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4362
                    goto efault;
4363
                old_act->_sa_handler = oact._sa_handler;
4364
                old_act->sa_flags = oact.sa_flags;
4365
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4366
                old_act->sa_mask.sig[1] = 0;
4367
                old_act->sa_mask.sig[2] = 0;
4368
                old_act->sa_mask.sig[3] = 0;
4369
                unlock_user_struct(old_act, arg3, 1);
4370
            }
4371
#endif
4372
        }
4373
        break;
4374
#endif
4375
    case TARGET_NR_rt_sigaction:
4376
        {
4377
            struct target_sigaction *act;
4378
            struct target_sigaction *oact;
4379

    
4380
            if (arg2) {
4381
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4382
                    goto efault;
4383
            } else
4384
                act = NULL;
4385
            if (arg3) {
4386
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4387
                    ret = -TARGET_EFAULT;
4388
                    goto rt_sigaction_fail;
4389
                }
4390
            } else
4391
                oact = NULL;
4392
            ret = get_errno(do_sigaction(arg1, act, oact));
4393
        rt_sigaction_fail:
4394
            if (act)
4395
                unlock_user_struct(act, arg2, 0);
4396
            if (oact)
4397
                unlock_user_struct(oact, arg3, 1);
4398
        }
4399
        break;
4400
#ifdef TARGET_NR_sgetmask /* not on alpha */
4401
    case TARGET_NR_sgetmask:
4402
        {
4403
            sigset_t cur_set;
4404
            abi_ulong target_set;
4405
            sigprocmask(0, NULL, &cur_set);
4406
            host_to_target_old_sigset(&target_set, &cur_set);
4407
            ret = target_set;
4408
        }
4409
        break;
4410
#endif
4411
#ifdef TARGET_NR_ssetmask /* not on alpha */
4412
    case TARGET_NR_ssetmask:
4413
        {
4414
            sigset_t set, oset, cur_set;
4415
            abi_ulong target_set = arg1;
4416
            sigprocmask(0, NULL, &cur_set);
4417
            target_to_host_old_sigset(&set, &target_set);
4418
            sigorset(&set, &set, &cur_set);
4419
            sigprocmask(SIG_SETMASK, &set, &oset);
4420
            host_to_target_old_sigset(&target_set, &oset);
4421
            ret = target_set;
4422
        }
4423
        break;
4424
#endif
4425
#ifdef TARGET_NR_sigprocmask
4426
    case TARGET_NR_sigprocmask:
4427
        {
4428
            int how = arg1;
4429
            sigset_t set, oldset, *set_ptr;
4430

    
4431
            if (arg2) {
4432
                switch(how) {
4433
                case TARGET_SIG_BLOCK:
4434
                    how = SIG_BLOCK;
4435
                    break;
4436
                case TARGET_SIG_UNBLOCK:
4437
                    how = SIG_UNBLOCK;
4438
                    break;
4439
                case TARGET_SIG_SETMASK:
4440
                    how = SIG_SETMASK;
4441
                    break;
4442
                default:
4443
                    ret = -TARGET_EINVAL;
4444
                    goto fail;
4445
                }
4446
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4447
                    goto efault;
4448
                target_to_host_old_sigset(&set, p);
4449
                unlock_user(p, arg2, 0);
4450
                set_ptr = &set;
4451
            } else {
4452
                how = 0;
4453
                set_ptr = NULL;
4454
            }
4455
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4456
            if (!is_error(ret) && arg3) {
4457
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4458
                    goto efault;
4459
                host_to_target_old_sigset(p, &oldset);
4460
                unlock_user(p, arg3, sizeof(target_sigset_t));
4461
            }
4462
        }
4463
        break;
4464
#endif
4465
    case TARGET_NR_rt_sigprocmask:
4466
        {
4467
            int how = arg1;
4468
            sigset_t set, oldset, *set_ptr;
4469

    
4470
            if (arg2) {
4471
                switch(how) {
4472
                case TARGET_SIG_BLOCK:
4473
                    how = SIG_BLOCK;
4474
                    break;
4475
                case TARGET_SIG_UNBLOCK:
4476
                    how = SIG_UNBLOCK;
4477
                    break;
4478
                case TARGET_SIG_SETMASK:
4479
                    how = SIG_SETMASK;
4480
                    break;
4481
                default:
4482
                    ret = -TARGET_EINVAL;
4483
                    goto fail;
4484
                }
4485
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4486
                    goto efault;
4487
                target_to_host_sigset(&set, p);
4488
                unlock_user(p, arg2, 0);
4489
                set_ptr = &set;
4490
            } else {
4491
                how = 0;
4492
                set_ptr = NULL;
4493
            }
4494
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4495
            if (!is_error(ret) && arg3) {
4496
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4497
                    goto efault;
4498
                host_to_target_sigset(p, &oldset);
4499
                unlock_user(p, arg3, sizeof(target_sigset_t));
4500
            }
4501
        }
4502
        break;
4503
#ifdef TARGET_NR_sigpending
4504
    case TARGET_NR_sigpending:
4505
        {
4506
            sigset_t set;
4507
            ret = get_errno(sigpending(&set));
4508
            if (!is_error(ret)) {
4509
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4510
                    goto efault;
4511
                host_to_target_old_sigset(p, &set);
4512
                unlock_user(p, arg1, sizeof(target_sigset_t));
4513
            }
4514
        }
4515
        break;
4516
#endif
4517
    case TARGET_NR_rt_sigpending:
4518
        {
4519
            sigset_t set;
4520
            ret = get_errno(sigpending(&set));
4521
            if (!is_error(ret)) {
4522
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4523
                    goto efault;
4524
                host_to_target_sigset(p, &set);
4525
                unlock_user(p, arg1, sizeof(target_sigset_t));
4526
            }
4527
        }
4528
        break;
4529
#ifdef TARGET_NR_sigsuspend
4530
    case TARGET_NR_sigsuspend:
4531
        {
4532
            sigset_t set;
4533
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4534
                goto efault;
4535
            target_to_host_old_sigset(&set, p);
4536
            unlock_user(p, arg1, 0);
4537
            ret = get_errno(sigsuspend(&set));
4538
        }
4539
        break;
4540
#endif
4541
    case TARGET_NR_rt_sigsuspend:
4542
        {
4543
            sigset_t set;
4544
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4545
                goto efault;
4546
            target_to_host_sigset(&set, p);
4547
            unlock_user(p, arg1, 0);
4548
            ret = get_errno(sigsuspend(&set));
4549
        }
4550
        break;
4551
    case TARGET_NR_rt_sigtimedwait:
4552
        {
4553
            sigset_t set;
4554
            struct timespec uts, *puts;
4555
            siginfo_t uinfo;
4556

    
4557
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4558
                goto efault;
4559
            target_to_host_sigset(&set, p);
4560
            unlock_user(p, arg1, 0);
4561
            if (arg3) {
4562
                puts = &uts;
4563
                target_to_host_timespec(puts, arg3);
4564
            } else {
4565
                puts = NULL;
4566
            }
4567
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4568
            if (!is_error(ret) && arg2) {
4569
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4570
                    goto efault;
4571
                host_to_target_siginfo(p, &uinfo);
4572
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4573
            }
4574
        }
4575
        break;
4576
    case TARGET_NR_rt_sigqueueinfo:
4577
        {
4578
            siginfo_t uinfo;
4579
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4580
                goto efault;
4581
            target_to_host_siginfo(&uinfo, p);
4582
            unlock_user(p, arg1, 0);
4583
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4584
        }
4585
        break;
4586
#ifdef TARGET_NR_sigreturn
4587
    case TARGET_NR_sigreturn:
4588
        /* NOTE: ret is eax, so not transcoding must be done */
4589
        ret = do_sigreturn(cpu_env);
4590
        break;
4591
#endif
4592
    case TARGET_NR_rt_sigreturn:
4593
        /* NOTE: ret is eax, so not transcoding must be done */
4594
        ret = do_rt_sigreturn(cpu_env);
4595
        break;
4596
    case TARGET_NR_sethostname:
4597
        if (!(p = lock_user_string(arg1)))
4598
            goto efault;
4599
        ret = get_errno(sethostname(p, arg2));
4600
        unlock_user(p, arg1, 0);
4601
        break;
4602
    case TARGET_NR_setrlimit:
4603
        {
4604
            /* XXX: convert resource ? */
4605
            int resource = arg1;
4606
            struct target_rlimit *target_rlim;
4607
            struct rlimit rlim;
4608
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4609
                goto efault;
4610
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4611
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4612
            unlock_user_struct(target_rlim, arg2, 0);
4613
            ret = get_errno(setrlimit(resource, &rlim));
4614
        }
4615
        break;
4616
    case TARGET_NR_getrlimit:
4617
        {
4618
            /* XXX: convert resource ? */
4619
            int resource = arg1;
4620
            struct target_rlimit *target_rlim;
4621
            struct rlimit rlim;
4622

    
4623
            ret = get_errno(getrlimit(resource, &rlim));
4624
            if (!is_error(ret)) {
4625
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4626
                    goto efault;
4627
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4628
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4629
                unlock_user_struct(target_rlim, arg2, 1);
4630
            }
4631
        }
4632
        break;
4633
    case TARGET_NR_getrusage:
4634
        {
4635
            struct rusage rusage;
4636
            ret = get_errno(getrusage(arg1, &rusage));
4637
            if (!is_error(ret)) {
4638
                host_to_target_rusage(arg2, &rusage);
4639
            }
4640
        }
4641
        break;
4642
    case TARGET_NR_gettimeofday:
4643
        {
4644
            struct timeval tv;
4645
            ret = get_errno(gettimeofday(&tv, NULL));
4646
            if (!is_error(ret)) {
4647
                if (copy_to_user_timeval(arg1, &tv))
4648
                    goto efault;
4649
            }
4650
        }
4651
        break;
4652
    case TARGET_NR_settimeofday:
4653
        {
4654
            struct timeval tv;
4655
            if (copy_from_user_timeval(&tv, arg1))
4656
                goto efault;
4657
            ret = get_errno(settimeofday(&tv, NULL));
4658
        }
4659
        break;
4660
#ifdef TARGET_NR_select
4661
    case TARGET_NR_select:
4662
        {
4663
            struct target_sel_arg_struct *sel;
4664
            abi_ulong inp, outp, exp, tvp;
4665
            long nsel;
4666

    
4667
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4668
                goto efault;
4669
            nsel = tswapl(sel->n);
4670
            inp = tswapl(sel->inp);
4671
            outp = tswapl(sel->outp);
4672
            exp = tswapl(sel->exp);
4673
            tvp = tswapl(sel->tvp);
4674
            unlock_user_struct(sel, arg1, 0);
4675
            ret = do_select(nsel, inp, outp, exp, tvp);
4676
        }
4677
        break;
4678
#endif
4679
    case TARGET_NR_symlink:
4680
        {
4681
            void *p2;
4682
            p = lock_user_string(arg1);
4683
            p2 = lock_user_string(arg2);
4684
            if (!p || !p2)
4685
                ret = -TARGET_EFAULT;
4686
            else
4687
                ret = get_errno(symlink(p, p2));
4688
            unlock_user(p2, arg2, 0);
4689
            unlock_user(p, arg1, 0);
4690
        }
4691
        break;
4692
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4693
    case TARGET_NR_symlinkat:
4694
        {
4695
            void *p2;
4696
            p  = lock_user_string(arg1);
4697
            p2 = lock_user_string(arg3);
4698
            if (!p || !p2)
4699
                ret = -TARGET_EFAULT;
4700
            else
4701
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4702
            unlock_user(p2, arg3, 0);
4703
            unlock_user(p, arg1, 0);
4704
        }
4705
        break;
4706
#endif
4707
#ifdef TARGET_NR_oldlstat
4708
    case TARGET_NR_oldlstat:
4709
        goto unimplemented;
4710
#endif
4711
    case TARGET_NR_readlink:
4712
        {
4713
            void *p2, *temp;
4714
            p = lock_user_string(arg1);
4715
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4716
            if (!p || !p2)
4717
                ret = -TARGET_EFAULT;
4718
            else {
4719
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4720
                    char real[PATH_MAX];
4721
                    temp = realpath(exec_path,real);
4722
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4723
                    snprintf((char *)p2, arg3, "%s", real);
4724
                    }
4725
                else
4726
                    ret = get_errno(readlink(path(p), p2, arg3));
4727
            }
4728
            unlock_user(p2, arg2, ret);
4729
            unlock_user(p, arg1, 0);
4730
        }
4731
        break;
4732
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4733
    case TARGET_NR_readlinkat:
4734
        {
4735
            void *p2;
4736
            p  = lock_user_string(arg2);
4737
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4738
            if (!p || !p2)
4739
                ret = -TARGET_EFAULT;
4740
            else
4741
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4742
            unlock_user(p2, arg3, ret);
4743
            unlock_user(p, arg2, 0);
4744
        }
4745
        break;
4746
#endif
4747
#ifdef TARGET_NR_uselib
4748
    case TARGET_NR_uselib:
4749
        goto unimplemented;
4750
#endif
4751
#ifdef TARGET_NR_swapon
4752
    case TARGET_NR_swapon:
4753
        if (!(p = lock_user_string(arg1)))
4754
            goto efault;
4755
        ret = get_errno(swapon(p, arg2));
4756
        unlock_user(p, arg1, 0);
4757
        break;
4758
#endif
4759
    case TARGET_NR_reboot:
4760
        goto unimplemented;
4761
#ifdef TARGET_NR_readdir
4762
    case TARGET_NR_readdir:
4763
        goto unimplemented;
4764
#endif
4765
#ifdef TARGET_NR_mmap
4766
    case TARGET_NR_mmap:
4767
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4768
        {
4769
            abi_ulong *v;
4770
            abi_ulong v1, v2, v3, v4, v5, v6;
4771
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4772
                goto efault;
4773
            v1 = tswapl(v[0]);
4774
            v2 = tswapl(v[1]);
4775
            v3 = tswapl(v[2]);
4776
            v4 = tswapl(v[3]);
4777
            v5 = tswapl(v[4]);
4778
            v6 = tswapl(v[5]);
4779
            unlock_user(v, arg1, 0);
4780
            ret = get_errno(target_mmap(v1, v2, v3,
4781
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4782
                                        v5, v6));
4783
        }
4784
#else
4785
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4786
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4787
                                    arg5,
4788
                                    arg6));
4789
#endif
4790
        break;
4791
#endif
4792
#ifdef TARGET_NR_mmap2
4793
    case TARGET_NR_mmap2:
4794
#ifndef MMAP_SHIFT
4795
#define MMAP_SHIFT 12
4796
#endif
4797
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4798
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4799
                                    arg5,
4800
                                    arg6 << MMAP_SHIFT));
4801
        break;
4802
#endif
4803
    case TARGET_NR_munmap:
4804
        ret = get_errno(target_munmap(arg1, arg2));
4805
        break;
4806
    case TARGET_NR_mprotect:
4807
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4808
        break;
4809
#ifdef TARGET_NR_mremap
4810
    case TARGET_NR_mremap:
4811
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4812
        break;
4813
#endif
4814
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4815
#ifdef TARGET_NR_msync
4816
    case TARGET_NR_msync:
4817
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4818
        break;
4819
#endif
4820
#ifdef TARGET_NR_mlock
4821
    case TARGET_NR_mlock:
4822
        ret = get_errno(mlock(g2h(arg1), arg2));
4823
        break;
4824
#endif
4825
#ifdef TARGET_NR_munlock
4826
    case TARGET_NR_munlock:
4827
        ret = get_errno(munlock(g2h(arg1), arg2));
4828
        break;
4829
#endif
4830
#ifdef TARGET_NR_mlockall
4831
    case TARGET_NR_mlockall:
4832
        ret = get_errno(mlockall(arg1));
4833
        break;
4834
#endif
4835
#ifdef TARGET_NR_munlockall
4836
    case TARGET_NR_munlockall:
4837
        ret = get_errno(munlockall());
4838
        break;
4839
#endif
4840
    case TARGET_NR_truncate:
4841
        if (!(p = lock_user_string(arg1)))
4842
            goto efault;
4843
        ret = get_errno(truncate(p, arg2));
4844
        unlock_user(p, arg1, 0);
4845
        break;
4846
    case TARGET_NR_ftruncate:
4847
        ret = get_errno(ftruncate(arg1, arg2));
4848
        break;
4849
    case TARGET_NR_fchmod:
4850
        ret = get_errno(fchmod(arg1, arg2));
4851
        break;
4852
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4853
    case TARGET_NR_fchmodat:
4854
        if (!(p = lock_user_string(arg2)))
4855
            goto efault;
4856
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4857
        unlock_user(p, arg2, 0);
4858
        break;
4859
#endif
4860
    case TARGET_NR_getpriority:
4861
        /* libc does special remapping of the return value of
4862
         * sys_getpriority() so it's just easiest to call
4863
         * sys_getpriority() directly rather than through libc. */
4864
        ret = sys_getpriority(arg1, arg2);
4865
        break;
4866
    case TARGET_NR_setpriority:
4867
        ret = get_errno(setpriority(arg1, arg2, arg3));
4868
        break;
4869
#ifdef TARGET_NR_profil
4870
    case TARGET_NR_profil:
4871
        goto unimplemented;
4872
#endif
4873
    case TARGET_NR_statfs:
4874
        if (!(p = lock_user_string(arg1)))
4875
            goto efault;
4876
        ret = get_errno(statfs(path(p), &stfs));
4877
        unlock_user(p, arg1, 0);
4878
    convert_statfs:
4879
        if (!is_error(ret)) {
4880
            struct target_statfs *target_stfs;
4881

    
4882
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4883
                goto efault;
4884
            __put_user(stfs.f_type, &target_stfs->f_type);
4885
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4886
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4887
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4888
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4889
            __put_user(stfs.f_files, &target_stfs->f_files);
4890
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4891
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4892
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4893
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4894
            unlock_user_struct(target_stfs, arg2, 1);
4895
        }
4896
        break;
4897
    case TARGET_NR_fstatfs:
4898
        ret = get_errno(fstatfs(arg1, &stfs));
4899
        goto convert_statfs;
4900
#ifdef TARGET_NR_statfs64
4901
    case TARGET_NR_statfs64:
4902
        if (!(p = lock_user_string(arg1)))
4903
            goto efault;
4904
        ret = get_errno(statfs(path(p), &stfs));
4905
        unlock_user(p, arg1, 0);
4906
    convert_statfs64:
4907
        if (!is_error(ret)) {
4908
            struct target_statfs64 *target_stfs;
4909

    
4910
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4911
                goto efault;
4912
            __put_user(stfs.f_type, &target_stfs->f_type);
4913
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4914
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4915
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4916
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4917
            __put_user(stfs.f_files, &target_stfs->f_files);
4918
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4919
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4920
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4921
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4922
            unlock_user_struct(target_stfs, arg3, 1);
4923
        }
4924
        break;
4925
    case TARGET_NR_fstatfs64:
4926
        ret = get_errno(fstatfs(arg1, &stfs));
4927
        goto convert_statfs64;
4928
#endif
4929
#ifdef TARGET_NR_ioperm
4930
    case TARGET_NR_ioperm:
4931
        goto unimplemented;
4932
#endif
4933
#ifdef TARGET_NR_socketcall
4934
    case TARGET_NR_socketcall:
4935
        ret = do_socketcall(arg1, arg2);
4936
        break;
4937
#endif
4938
#ifdef TARGET_NR_accept
4939
    case TARGET_NR_accept:
4940
        ret = do_accept(arg1, arg2, arg3);
4941
        break;
4942
#endif
4943
#ifdef TARGET_NR_bind
4944
    case TARGET_NR_bind:
4945
        ret = do_bind(arg1, arg2, arg3);
4946
        break;
4947
#endif
4948
#ifdef TARGET_NR_connect
4949
    case TARGET_NR_connect:
4950
        ret = do_connect(arg1, arg2, arg3);
4951
        break;
4952
#endif
4953
#ifdef TARGET_NR_getpeername
4954
    case TARGET_NR_getpeername:
4955
        ret = do_getpeername(arg1, arg2, arg3);
4956
        break;
4957
#endif
4958
#ifdef TARGET_NR_getsockname
4959
    case TARGET_NR_getsockname:
4960
        ret = do_getsockname(arg1, arg2, arg3);
4961
        break;
4962
#endif
4963
#ifdef TARGET_NR_getsockopt
4964
    case TARGET_NR_getsockopt:
4965
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4966
        break;
4967
#endif
4968
#ifdef TARGET_NR_listen
4969
    case TARGET_NR_listen:
4970
        ret = get_errno(listen(arg1, arg2));
4971
        break;
4972
#endif
4973
#ifdef TARGET_NR_recv
4974
    case TARGET_NR_recv:
4975
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4976
        break;
4977
#endif
4978
#ifdef TARGET_NR_recvfrom
4979
    case TARGET_NR_recvfrom:
4980
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4981
        break;
4982
#endif
4983
#ifdef TARGET_NR_recvmsg
4984
    case TARGET_NR_recvmsg:
4985
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4986
        break;
4987
#endif
4988
#ifdef TARGET_NR_send
4989
    case TARGET_NR_send:
4990
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4991
        break;
4992
#endif
4993
#ifdef TARGET_NR_sendmsg
4994
    case TARGET_NR_sendmsg:
4995
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4996
        break;
4997
#endif
4998
#ifdef TARGET_NR_sendto
4999
    case TARGET_NR_sendto:
5000
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5001
        break;
5002
#endif
5003
#ifdef TARGET_NR_shutdown
5004
    case TARGET_NR_shutdown:
5005
        ret = get_errno(shutdown(arg1, arg2));
5006
        break;
5007
#endif
5008
#ifdef TARGET_NR_socket
5009
    case TARGET_NR_socket:
5010
        ret = do_socket(arg1, arg2, arg3);
5011
        break;
5012
#endif
5013
#ifdef TARGET_NR_socketpair
5014
    case TARGET_NR_socketpair:
5015
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5016
        break;
5017
#endif
5018
#ifdef TARGET_NR_setsockopt
5019
    case TARGET_NR_setsockopt:
5020
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5021
        break;
5022
#endif
5023

    
5024
    case TARGET_NR_syslog:
5025
        if (!(p = lock_user_string(arg2)))
5026
            goto efault;
5027
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5028
        unlock_user(p, arg2, 0);
5029
        break;
5030

    
5031
    case TARGET_NR_setitimer:
5032
        {
5033
            struct itimerval value, ovalue, *pvalue;
5034

    
5035
            if (arg2) {
5036
                pvalue = &value;
5037
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5038
                    || copy_from_user_timeval(&pvalue->it_value,
5039
                                              arg2 + sizeof(struct target_timeval)))
5040
                    goto efault;
5041
            } else {
5042
                pvalue = NULL;
5043
            }
5044
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5045
            if (!is_error(ret) && arg3) {
5046
                if (copy_to_user_timeval(arg3,
5047
                                         &ovalue.it_interval)
5048
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5049
                                            &ovalue.it_value))
5050
                    goto efault;
5051
            }
5052
        }
5053
        break;
5054
    case TARGET_NR_getitimer:
5055
        {
5056
            struct itimerval value;
5057

    
5058
            ret = get_errno(getitimer(arg1, &value));
5059
            if (!is_error(ret) && arg2) {
5060
                if (copy_to_user_timeval(arg2,
5061
                                         &value.it_interval)
5062
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5063
                                            &value.it_value))
5064
                    goto efault;
5065
            }
5066
        }
5067
        break;
5068
    case TARGET_NR_stat:
5069
        if (!(p = lock_user_string(arg1)))
5070
            goto efault;
5071
        ret = get_errno(stat(path(p), &st));
5072
        unlock_user(p, arg1, 0);
5073
        goto do_stat;
5074
    case TARGET_NR_lstat:
5075
        if (!(p = lock_user_string(arg1)))
5076
            goto efault;
5077
        ret = get_errno(lstat(path(p), &st));
5078
        unlock_user(p, arg1, 0);
5079
        goto do_stat;
5080
    case TARGET_NR_fstat:
5081
        {
5082
            ret = get_errno(fstat(arg1, &st));
5083
        do_stat:
5084
            if (!is_error(ret)) {
5085
                struct target_stat *target_st;
5086

    
5087
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5088
                    goto efault;
5089
                __put_user(st.st_dev, &target_st->st_dev);
5090
                __put_user(st.st_ino, &target_st->st_ino);
5091
                __put_user(st.st_mode, &target_st->st_mode);
5092
                __put_user(st.st_uid, &target_st->st_uid);
5093
                __put_user(st.st_gid, &target_st->st_gid);
5094
                __put_user(st.st_nlink, &target_st->st_nlink);
5095
                __put_user(st.st_rdev, &target_st->st_rdev);
5096
                __put_user(st.st_size, &target_st->st_size);
5097
                __put_user(st.st_blksize, &target_st->st_blksize);
5098
                __put_user(st.st_blocks, &target_st->st_blocks);
5099
                __put_user(st.st_atime, &target_st->target_st_atime);
5100
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5101
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5102
                unlock_user_struct(target_st, arg2, 1);
5103
            }
5104
        }
5105
        break;
5106
#ifdef TARGET_NR_olduname
5107
    case TARGET_NR_olduname:
5108
        goto unimplemented;
5109
#endif
5110
#ifdef TARGET_NR_iopl
5111
    case TARGET_NR_iopl:
5112
        goto unimplemented;
5113
#endif
5114
    case TARGET_NR_vhangup:
5115
        ret = get_errno(vhangup());
5116
        break;
5117
#ifdef TARGET_NR_idle
5118
    case TARGET_NR_idle:
5119
        goto unimplemented;
5120
#endif
5121
#ifdef TARGET_NR_syscall
5122
    case TARGET_NR_syscall:
5123
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5124
            break;
5125
#endif
5126
    case TARGET_NR_wait4:
5127
        {
5128
            int status;
5129
            abi_long status_ptr = arg2;
5130
            struct rusage rusage, *rusage_ptr;
5131
            abi_ulong target_rusage = arg4;
5132
            if (target_rusage)
5133
                rusage_ptr = &rusage;
5134
            else
5135
                rusage_ptr = NULL;
5136
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5137
            if (!is_error(ret)) {
5138
                if (status_ptr) {
5139
                    if (put_user_s32(status, status_ptr))
5140
                        goto efault;
5141
                }
5142
                if (target_rusage)
5143
                    host_to_target_rusage(target_rusage, &rusage);
5144
            }
5145
        }
5146
        break;
5147
#ifdef TARGET_NR_swapoff
5148
    case TARGET_NR_swapoff:
5149
        if (!(p = lock_user_string(arg1)))
5150
            goto efault;
5151
        ret = get_errno(swapoff(p));
5152
        unlock_user(p, arg1, 0);
5153
        break;
5154
#endif
5155
    case TARGET_NR_sysinfo:
5156
        {
5157
            struct target_sysinfo *target_value;
5158
            struct sysinfo value;
5159
            ret = get_errno(sysinfo(&value));
5160
            if (!is_error(ret) && arg1)
5161
            {
5162
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5163
                    goto efault;
5164
                __put_user(value.uptime, &target_value->uptime);
5165
                __put_user(value.loads[0], &target_value->loads[0]);
5166
                __put_user(value.loads[1], &target_value->loads[1]);
5167
                __put_user(value.loads[2], &target_value->loads[2]);
5168
                __put_user(value.totalram, &target_value->totalram);
5169
                __put_user(value.freeram, &target_value->freeram);
5170
                __put_user(value.sharedram, &target_value->sharedram);
5171
                __put_user(value.bufferram, &target_value->bufferram);
5172
                __put_user(value.totalswap, &target_value->totalswap);
5173
                __put_user(value.freeswap, &target_value->freeswap);
5174
                __put_user(value.procs, &target_value->procs);
5175
                __put_user(value.totalhigh, &target_value->totalhigh);
5176
                __put_user(value.freehigh, &target_value->freehigh);
5177
                __put_user(value.mem_unit, &target_value->mem_unit);
5178
                unlock_user_struct(target_value, arg1, 1);
5179
            }
5180
        }
5181
        break;
5182
#ifdef TARGET_NR_ipc
5183
    case TARGET_NR_ipc:
5184
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5185
        break;
5186
#endif
5187

    
5188
#ifdef TARGET_NR_msgctl
5189
    case TARGET_NR_msgctl:
5190
        ret = do_msgctl(arg1, arg2, arg3);
5191
        break;
5192
#endif
5193
#ifdef TARGET_NR_msgget
5194
    case TARGET_NR_msgget:
5195
        ret = get_errno(msgget(arg1, arg2));
5196
        break;
5197
#endif
5198
#ifdef TARGET_NR_msgrcv
5199
    case TARGET_NR_msgrcv:
5200
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5201
        break;
5202
#endif
5203
#ifdef TARGET_NR_msgsnd
5204
    case TARGET_NR_msgsnd:
5205
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5206
        break;
5207
#endif
5208
    case TARGET_NR_fsync:
5209
        ret = get_errno(fsync(arg1));
5210
        break;
5211
    case TARGET_NR_clone:
5212
#if defined(TARGET_SH4)
5213
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5214
#elif defined(TARGET_CRIS)
5215
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5216
#else
5217
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5218
#endif
5219
        break;
5220
#ifdef __NR_exit_group
5221
        /* new thread calls */
5222
    case TARGET_NR_exit_group:
5223
#ifdef HAVE_GPROF
5224
        _mcleanup();
5225
#endif
5226
        gdb_exit(cpu_env, arg1);
5227
        ret = get_errno(exit_group(arg1));
5228
        break;
5229
#endif
5230
    case TARGET_NR_setdomainname:
5231
        if (!(p = lock_user_string(arg1)))
5232
            goto efault;
5233
        ret = get_errno(setdomainname(p, arg2));
5234
        unlock_user(p, arg1, 0);
5235
        break;
5236
    case TARGET_NR_uname:
5237
        /* no need to transcode because we use the linux syscall */
5238
        {
5239
            struct new_utsname * buf;
5240

    
5241
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5242
                goto efault;
5243
            ret = get_errno(sys_uname(buf));
5244
            if (!is_error(ret)) {
5245
                /* Overrite the native machine name with whatever is being
5246
                   emulated. */
5247
                strcpy (buf->machine, UNAME_MACHINE);
5248
                /* Allow the user to override the reported release.  */
5249
                if (qemu_uname_release && *qemu_uname_release)
5250
                  strcpy (buf->release, qemu_uname_release);
5251
            }
5252
            unlock_user_struct(buf, arg1, 1);
5253
        }
5254
        break;
5255
#ifdef TARGET_I386
5256
    case TARGET_NR_modify_ldt:
5257
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5258
        break;
5259
#if !defined(TARGET_X86_64)
5260
    case TARGET_NR_vm86old:
5261
        goto unimplemented;
5262
    case TARGET_NR_vm86:
5263
        ret = do_vm86(cpu_env, arg1, arg2);
5264
        break;
5265
#endif
5266
#endif
5267
    case TARGET_NR_adjtimex:
5268
        goto unimplemented;
5269
#ifdef TARGET_NR_create_module
5270
    case TARGET_NR_create_module:
5271
#endif
5272
    case TARGET_NR_init_module:
5273
    case TARGET_NR_delete_module:
5274
#ifdef TARGET_NR_get_kernel_syms
5275
    case TARGET_NR_get_kernel_syms:
5276
#endif
5277
        goto unimplemented;
5278
    case TARGET_NR_quotactl:
5279
        goto unimplemented;
5280
    case TARGET_NR_getpgid:
5281
        ret = get_errno(getpgid(arg1));
5282
        break;
5283
    case TARGET_NR_fchdir:
5284
        ret = get_errno(fchdir(arg1));
5285
        break;
5286
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5287
    case TARGET_NR_bdflush:
5288
        goto unimplemented;
5289
#endif
5290
#ifdef TARGET_NR_sysfs
5291
    case TARGET_NR_sysfs:
5292
        goto unimplemented;
5293
#endif
5294
    case TARGET_NR_personality:
5295
        ret = get_errno(personality(arg1));
5296
        break;
5297
#ifdef TARGET_NR_afs_syscall
5298
    case TARGET_NR_afs_syscall:
5299
        goto unimplemented;
5300
#endif
5301
#ifdef TARGET_NR__llseek /* Not on alpha */
5302
    case TARGET_NR__llseek:
5303
        {
5304
#if defined (__x86_64__)
5305
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5306
            if (put_user_s64(ret, arg4))
5307
                goto efault;
5308
#else
5309
            int64_t res;
5310
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5311
            if (put_user_s64(res, arg4))
5312
                goto efault;
5313
#endif
5314
        }
5315
        break;
5316
#endif
5317
    case TARGET_NR_getdents:
5318
#if TARGET_ABI_BITS != 32
5319
        goto unimplemented;
5320
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5321
        {
5322
            struct target_dirent *target_dirp;
5323
            struct linux_dirent *dirp;
5324
            abi_long count = arg3;
5325

    
5326
            dirp = malloc(count);
5327
            if (!dirp) {
5328
                ret = -TARGET_ENOMEM;
5329
                goto fail;
5330
            }
5331

    
5332
            ret = get_errno(sys_getdents(arg1, dirp, count));
5333
            if (!is_error(ret)) {
5334
                struct linux_dirent *de;
5335
                struct target_dirent *tde;
5336
                int len = ret;
5337
                int reclen, treclen;
5338
                int count1, tnamelen;
5339

    
5340
                count1 = 0;
5341
                de = dirp;
5342
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5343
                    goto efault;
5344
                tde = target_dirp;
5345
                while (len > 0) {
5346
                    reclen = de->d_reclen;
5347
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5348
                    tde->d_reclen = tswap16(treclen);
5349
                    tde->d_ino = tswapl(de->d_ino);
5350
                    tde->d_off = tswapl(de->d_off);
5351
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5352
                    if (tnamelen > 256)
5353
                        tnamelen = 256;
5354
                    /* XXX: may not be correct */
5355
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5356
                    de = (struct linux_dirent *)((char *)de + reclen);
5357
                    len -= reclen;
5358
                    tde = (struct target_dirent *)((char *)tde + treclen);
5359
                    count1 += treclen;
5360
                }
5361
                ret = count1;
5362
                unlock_user(target_dirp, arg2, ret);
5363
            }
5364
            free(dirp);
5365
        }
5366
#else
5367
        {
5368
            struct linux_dirent *dirp;
5369
            abi_long count = arg3;
5370

    
5371
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5372
                goto efault;
5373
            ret = get_errno(sys_getdents(arg1, dirp, count));
5374
            if (!is_error(ret)) {
5375
                struct linux_dirent *de;
5376
                int len = ret;
5377
                int reclen;
5378
                de = dirp;
5379
                while (len > 0) {
5380
                    reclen = de->d_reclen;
5381
                    if (reclen > len)
5382
                        break;
5383
                    de->d_reclen = tswap16(reclen);
5384
                    tswapls(&de->d_ino);
5385
                    tswapls(&de->d_off);
5386
                    de = (struct linux_dirent *)((char *)de + reclen);
5387
                    len -= reclen;
5388
                }
5389
            }
5390
            unlock_user(dirp, arg2, ret);
5391
        }
5392
#endif
5393
        break;
5394
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5395
    case TARGET_NR_getdents64:
5396
        {
5397
            struct linux_dirent64 *dirp;
5398
            abi_long count = arg3;
5399
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5400
                goto efault;
5401
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5402
            if (!is_error(ret)) {
5403
                struct linux_dirent64 *de;
5404
                int len = ret;
5405
                int reclen;
5406
                de = dirp;
5407
                while (len > 0) {
5408
                    reclen = de->d_reclen;
5409
                    if (reclen > len)
5410
                        break;
5411
                    de->d_reclen = tswap16(reclen);
5412
                    tswap64s((uint64_t *)&de->d_ino);
5413
                    tswap64s((uint64_t *)&de->d_off);
5414
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5415
                    len -= reclen;
5416
                }
5417
            }
5418
            unlock_user(dirp, arg2, ret);
5419
        }
5420
        break;
5421
#endif /* TARGET_NR_getdents64 */
5422
#ifdef TARGET_NR__newselect
5423
    case TARGET_NR__newselect:
5424
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5425
        break;
5426
#endif
5427
#ifdef TARGET_NR_poll
5428
    case TARGET_NR_poll:
5429
        {
5430
            struct target_pollfd *target_pfd;
5431
            unsigned int nfds = arg2;
5432
            int timeout = arg3;
5433
            struct pollfd *pfd;
5434
            unsigned int i;
5435

    
5436
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5437
            if (!target_pfd)
5438
                goto efault;
5439
            pfd = alloca(sizeof(struct pollfd) * nfds);
5440
            for(i = 0; i < nfds; i++) {
5441
                pfd[i].fd = tswap32(target_pfd[i].fd);
5442
                pfd[i].events = tswap16(target_pfd[i].events);
5443
            }
5444
            ret = get_errno(poll(pfd, nfds, timeout));
5445
            if (!is_error(ret)) {
5446
                for(i = 0; i < nfds; i++) {
5447
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5448
                }
5449
                ret += nfds * (sizeof(struct target_pollfd)
5450
                               - sizeof(struct pollfd));
5451
            }
5452
            unlock_user(target_pfd, arg1, ret);
5453
        }
5454
        break;
5455
#endif
5456
    case TARGET_NR_flock:
5457
        /* NOTE: the flock constant seems to be the same for every
5458
           Linux platform */
5459
        ret = get_errno(flock(arg1, arg2));
5460
        break;
5461
    case TARGET_NR_readv:
5462
        {
5463
            int count = arg3;
5464
            struct iovec *vec;
5465

    
5466
            vec = alloca(count * sizeof(struct iovec));
5467
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5468
                goto efault;
5469
            ret = get_errno(readv(arg1, vec, count));
5470
            unlock_iovec(vec, arg2, count, 1);
5471
        }
5472
        break;
5473
    case TARGET_NR_writev:
5474
        {
5475
            int count = arg3;
5476
            struct iovec *vec;
5477

    
5478
            vec = alloca(count * sizeof(struct iovec));
5479
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5480
                goto efault;
5481
            ret = get_errno(writev(arg1, vec, count));
5482
            unlock_iovec(vec, arg2, count, 0);
5483
        }
5484
        break;
5485
    case TARGET_NR_getsid:
5486
        ret = get_errno(getsid(arg1));
5487
        break;
5488
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5489
    case TARGET_NR_fdatasync:
5490
        ret = get_errno(fdatasync(arg1));
5491
        break;
5492
#endif
5493
    case TARGET_NR__sysctl:
5494
        /* We don't implement this, but ENOTDIR is always a safe
5495
           return value. */
5496
        ret = -TARGET_ENOTDIR;
5497
        break;
5498
    case TARGET_NR_sched_setparam:
5499
        {
5500
            struct sched_param *target_schp;
5501
            struct sched_param schp;
5502

    
5503
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5504
                goto efault;
5505
            schp.sched_priority = tswap32(target_schp->sched_priority);
5506
            unlock_user_struct(target_schp, arg2, 0);
5507
            ret = get_errno(sched_setparam(arg1, &schp));
5508
        }
5509
        break;
5510
    case TARGET_NR_sched_getparam:
5511
        {
5512
            struct sched_param *target_schp;
5513
            struct sched_param schp;
5514
            ret = get_errno(sched_getparam(arg1, &schp));
5515
            if (!is_error(ret)) {
5516
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5517
                    goto efault;
5518
                target_schp->sched_priority = tswap32(schp.sched_priority);
5519
                unlock_user_struct(target_schp, arg2, 1);
5520
            }
5521
        }
5522
        break;
5523
    case TARGET_NR_sched_setscheduler:
5524
        {
5525
            struct sched_param *target_schp;
5526
            struct sched_param schp;
5527
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5528
                goto efault;
5529
            schp.sched_priority = tswap32(target_schp->sched_priority);
5530
            unlock_user_struct(target_schp, arg3, 0);
5531
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5532
        }
5533
        break;
5534
    case TARGET_NR_sched_getscheduler:
5535
        ret = get_errno(sched_getscheduler(arg1));
5536
        break;
5537
    case TARGET_NR_sched_yield:
5538
        ret = get_errno(sched_yield());
5539
        break;
5540
    case TARGET_NR_sched_get_priority_max:
5541
        ret = get_errno(sched_get_priority_max(arg1));
5542
        break;
5543
    case TARGET_NR_sched_get_priority_min:
5544
        ret = get_errno(sched_get_priority_min(arg1));
5545
        break;
5546
    case TARGET_NR_sched_rr_get_interval:
5547
        {
5548
            struct timespec ts;
5549
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5550
            if (!is_error(ret)) {
5551
                host_to_target_timespec(arg2, &ts);
5552
            }
5553
        }
5554
        break;
5555
    case TARGET_NR_nanosleep:
5556
        {
5557
            struct timespec req, rem;
5558
            target_to_host_timespec(&req, arg1);
5559
            ret = get_errno(nanosleep(&req, &rem));
5560
            if (is_error(ret) && arg2) {
5561
                host_to_target_timespec(arg2, &rem);
5562
            }
5563
        }
5564
        break;
5565
#ifdef TARGET_NR_query_module
5566
    case TARGET_NR_query_module:
5567
        goto unimplemented;
5568
#endif
5569
#ifdef TARGET_NR_nfsservctl
5570
    case TARGET_NR_nfsservctl:
5571
        goto unimplemented;
5572
#endif
5573
    case TARGET_NR_prctl:
5574
        switch (arg1)
5575
            {
5576
            case PR_GET_PDEATHSIG:
5577
                {
5578
                    int deathsig;
5579
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5580
                    if (!is_error(ret) && arg2
5581
                        && put_user_ual(deathsig, arg2))
5582
                        goto efault;
5583
                }
5584
                break;
5585
            default:
5586
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5587
                break;
5588
            }
5589
        break;
5590
#ifdef TARGET_NR_arch_prctl
5591
    case TARGET_NR_arch_prctl:
5592
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5593
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5594
        break;
5595
#else
5596
        goto unimplemented;
5597
#endif
5598
#endif
5599
#ifdef TARGET_NR_pread
5600
    case TARGET_NR_pread:
5601
#ifdef TARGET_ARM
5602
        if (((CPUARMState *)cpu_env)->eabi)
5603
            arg4 = arg5;
5604
#endif
5605
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5606
            goto efault;
5607
        ret = get_errno(pread(arg1, p, arg3, arg4));
5608
        unlock_user(p, arg2, ret);
5609
        break;
5610
    case TARGET_NR_pwrite:
5611
#ifdef TARGET_ARM
5612
        if (((CPUARMState *)cpu_env)->eabi)
5613
            arg4 = arg5;
5614
#endif
5615
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5616
            goto efault;
5617
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5618
        unlock_user(p, arg2, 0);
5619
        break;
5620
#endif
5621
#ifdef TARGET_NR_pread64
5622
    case TARGET_NR_pread64:
5623
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5624
            goto efault;
5625
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5626
        unlock_user(p, arg2, ret);
5627
        break;
5628
    case TARGET_NR_pwrite64:
5629
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5630
            goto efault;
5631
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5632
        unlock_user(p, arg2, 0);
5633
        break;
5634
#endif
5635
    case TARGET_NR_getcwd:
5636
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5637
            goto efault;
5638
        ret = get_errno(sys_getcwd1(p, arg2));
5639
        unlock_user(p, arg1, ret);
5640
        break;
5641
    case TARGET_NR_capget:
5642
        goto unimplemented;
5643
    case TARGET_NR_capset:
5644
        goto unimplemented;
5645
    case TARGET_NR_sigaltstack:
5646
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5647
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5648
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5649
        break;
5650
#else
5651
        goto unimplemented;
5652
#endif
5653
    case TARGET_NR_sendfile:
5654
        goto unimplemented;
5655
#ifdef TARGET_NR_getpmsg
5656
    case TARGET_NR_getpmsg:
5657
        goto unimplemented;
5658
#endif
5659
#ifdef TARGET_NR_putpmsg
5660
    case TARGET_NR_putpmsg:
5661
        goto unimplemented;
5662
#endif
5663
#ifdef TARGET_NR_vfork
5664
    case TARGET_NR_vfork:
5665
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5666
                        0, 0, 0, 0));
5667
        break;
5668
#endif
5669
#ifdef TARGET_NR_ugetrlimit
5670
    case TARGET_NR_ugetrlimit:
5671
    {
5672
        struct rlimit rlim;
5673
        ret = get_errno(getrlimit(arg1, &rlim));
5674
        if (!is_error(ret)) {
5675
            struct target_rlimit *target_rlim;
5676
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5677
                goto efault;
5678
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5679
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5680
            unlock_user_struct(target_rlim, arg2, 1);
5681
        }
5682
        break;
5683
    }
5684
#endif
5685
#ifdef TARGET_NR_truncate64
5686
    case TARGET_NR_truncate64:
5687
        if (!(p = lock_user_string(arg1)))
5688
            goto efault;
5689
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5690
        unlock_user(p, arg1, 0);
5691
        break;
5692
#endif
5693
#ifdef TARGET_NR_ftruncate64
5694
    case TARGET_NR_ftruncate64:
5695
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5696
        break;
5697
#endif
5698
#ifdef TARGET_NR_stat64
5699
    case TARGET_NR_stat64:
5700
        if (!(p = lock_user_string(arg1)))
5701
            goto efault;
5702
        ret = get_errno(stat(path(p), &st));
5703
        unlock_user(p, arg1, 0);
5704
        if (!is_error(ret))
5705
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5706
        break;
5707
#endif
5708
#ifdef TARGET_NR_lstat64
5709
    case TARGET_NR_lstat64:
5710
        if (!(p = lock_user_string(arg1)))
5711
            goto efault;
5712
        ret = get_errno(lstat(path(p), &st));
5713
        unlock_user(p, arg1, 0);
5714
        if (!is_error(ret))
5715
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5716
        break;
5717
#endif
5718
#ifdef TARGET_NR_fstat64
5719
    case TARGET_NR_fstat64:
5720
        ret = get_errno(fstat(arg1, &st));
5721
        if (!is_error(ret))
5722
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5723
        break;
5724
#endif
5725
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
5726
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
5727
#ifdef TARGET_NR_fstatat64
5728
    case TARGET_NR_fstatat64:
5729
#endif
5730
#ifdef TARGET_NR_newfstatat
5731
    case TARGET_NR_newfstatat:
5732
#endif
5733
        if (!(p = lock_user_string(arg2)))
5734
            goto efault;
5735
#ifdef __NR_fstatat64
5736
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5737
#else
5738
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
5739
#endif
5740
        if (!is_error(ret))
5741
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5742
        break;
5743
#endif
5744
#ifdef USE_UID16
5745
    case TARGET_NR_lchown:
5746
        if (!(p = lock_user_string(arg1)))
5747
            goto efault;
5748
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5749
        unlock_user(p, arg1, 0);
5750
        break;
5751
    case TARGET_NR_getuid:
5752
        ret = get_errno(high2lowuid(getuid()));
5753
        break;
5754
    case TARGET_NR_getgid:
5755
        ret = get_errno(high2lowgid(getgid()));
5756
        break;
5757
    case TARGET_NR_geteuid:
5758
        ret = get_errno(high2lowuid(geteuid()));
5759
        break;
5760
    case TARGET_NR_getegid:
5761
        ret = get_errno(high2lowgid(getegid()));
5762
        break;
5763
    case TARGET_NR_setreuid:
5764
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5765
        break;
5766
    case TARGET_NR_setregid:
5767
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5768
        break;
5769
    case TARGET_NR_getgroups:
5770
        {
5771
            int gidsetsize = arg1;
5772
            uint16_t *target_grouplist;
5773
            gid_t *grouplist;
5774
            int i;
5775

    
5776
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5777
            ret = get_errno(getgroups(gidsetsize, grouplist));
5778
            if (gidsetsize == 0)
5779
                break;
5780
            if (!is_error(ret)) {
5781
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5782
                if (!target_grouplist)
5783
                    goto efault;
5784
                for(i = 0;i < ret; i++)
5785
                    target_grouplist[i] = tswap16(grouplist[i]);
5786
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5787
            }
5788
        }
5789
        break;
5790
    case TARGET_NR_setgroups:
5791
        {
5792
            int gidsetsize = arg1;
5793
            uint16_t *target_grouplist;
5794
            gid_t *grouplist;
5795
            int i;
5796

    
5797
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5798
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5799
            if (!target_grouplist) {
5800
                ret = -TARGET_EFAULT;
5801
                goto fail;
5802
            }
5803
            for(i = 0;i < gidsetsize; i++)
5804
                grouplist[i] = tswap16(target_grouplist[i]);
5805
            unlock_user(target_grouplist, arg2, 0);
5806
            ret = get_errno(setgroups(gidsetsize, grouplist));
5807
        }
5808
        break;
5809
    case TARGET_NR_fchown:
5810
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5811
        break;
5812
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5813
    case TARGET_NR_fchownat:
5814
        if (!(p = lock_user_string(arg2))) 
5815
            goto efault;
5816
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5817
        unlock_user(p, arg2, 0);
5818
        break;
5819
#endif
5820
#ifdef TARGET_NR_setresuid
5821
    case TARGET_NR_setresuid:
5822
        ret = get_errno(setresuid(low2highuid(arg1),
5823
                                  low2highuid(arg2),
5824
                                  low2highuid(arg3)));
5825
        break;
5826
#endif
5827
#ifdef TARGET_NR_getresuid
5828
    case TARGET_NR_getresuid:
5829
        {
5830
            uid_t ruid, euid, suid;
5831
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5832
            if (!is_error(ret)) {
5833
                if (put_user_u16(high2lowuid(ruid), arg1)
5834
                    || put_user_u16(high2lowuid(euid), arg2)
5835
                    || put_user_u16(high2lowuid(suid), arg3))
5836
                    goto efault;
5837
            }
5838
        }
5839
        break;
5840
#endif
5841
#ifdef TARGET_NR_getresgid
5842
    case TARGET_NR_setresgid:
5843
        ret = get_errno(setresgid(low2highgid(arg1),
5844
                                  low2highgid(arg2),
5845
                                  low2highgid(arg3)));
5846
        break;
5847
#endif
5848
#ifdef TARGET_NR_getresgid
5849
    case TARGET_NR_getresgid:
5850
        {
5851
            gid_t rgid, egid, sgid;
5852
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5853
            if (!is_error(ret)) {
5854
                if (put_user_u16(high2lowgid(rgid), arg1)
5855
                    || put_user_u16(high2lowgid(egid), arg2)
5856
                    || put_user_u16(high2lowgid(sgid), arg3))
5857
                    goto efault;
5858
            }
5859
        }
5860
        break;
5861
#endif
5862
    case TARGET_NR_chown:
5863
        if (!(p = lock_user_string(arg1)))
5864
            goto efault;
5865
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5866
        unlock_user(p, arg1, 0);
5867
        break;
5868
    case TARGET_NR_setuid:
5869
        ret = get_errno(setuid(low2highuid(arg1)));
5870
        break;
5871
    case TARGET_NR_setgid:
5872
        ret = get_errno(setgid(low2highgid(arg1)));
5873
        break;
5874
    case TARGET_NR_setfsuid:
5875
        ret = get_errno(setfsuid(arg1));
5876
        break;
5877
    case TARGET_NR_setfsgid:
5878
        ret = get_errno(setfsgid(arg1));
5879
        break;
5880
#endif /* USE_UID16 */
5881

    
5882
#ifdef TARGET_NR_lchown32
5883
    case TARGET_NR_lchown32:
5884
        if (!(p = lock_user_string(arg1)))
5885
            goto efault;
5886
        ret = get_errno(lchown(p, arg2, arg3));
5887
        unlock_user(p, arg1, 0);
5888
        break;
5889
#endif
5890
#ifdef TARGET_NR_getuid32
5891
    case TARGET_NR_getuid32:
5892
        ret = get_errno(getuid());
5893
        break;
5894
#endif
5895

    
5896
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5897
   /* Alpha specific */
5898
    case TARGET_NR_getxuid:
5899
         {
5900
            uid_t euid;
5901
            euid=geteuid();
5902
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5903
         }
5904
        ret = get_errno(getuid());
5905
        break;
5906
#endif
5907
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5908
   /* Alpha specific */
5909
    case TARGET_NR_getxgid:
5910
         {
5911
            uid_t egid;
5912
            egid=getegid();
5913
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5914
         }
5915
        ret = get_errno(getgid());
5916
        break;
5917
#endif
5918

    
5919
#ifdef TARGET_NR_getgid32
5920
    case TARGET_NR_getgid32:
5921
        ret = get_errno(getgid());
5922
        break;
5923
#endif
5924
#ifdef TARGET_NR_geteuid32
5925
    case TARGET_NR_geteuid32:
5926
        ret = get_errno(geteuid());
5927
        break;
5928
#endif
5929
#ifdef TARGET_NR_getegid32
5930
    case TARGET_NR_getegid32:
5931
        ret = get_errno(getegid());
5932
        break;
5933
#endif
5934
#ifdef TARGET_NR_setreuid32
5935
    case TARGET_NR_setreuid32:
5936
        ret = get_errno(setreuid(arg1, arg2));
5937
        break;
5938
#endif
5939
#ifdef TARGET_NR_setregid32
5940
    case TARGET_NR_setregid32:
5941
        ret = get_errno(setregid(arg1, arg2));
5942
        break;
5943
#endif
5944
#ifdef TARGET_NR_getgroups32
5945
    case TARGET_NR_getgroups32:
5946
        {
5947
            int gidsetsize = arg1;
5948
            uint32_t *target_grouplist;
5949
            gid_t *grouplist;
5950
            int i;
5951

    
5952
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5953
            ret = get_errno(getgroups(gidsetsize, grouplist));
5954
            if (gidsetsize == 0)
5955
                break;
5956
            if (!is_error(ret)) {
5957
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5958
                if (!target_grouplist) {
5959
                    ret = -TARGET_EFAULT;
5960
                    goto fail;
5961
                }
5962
                for(i = 0;i < ret; i++)
5963
                    target_grouplist[i] = tswap32(grouplist[i]);
5964
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5965
            }
5966
        }
5967
        break;
5968
#endif
5969
#ifdef TARGET_NR_setgroups32
5970
    case TARGET_NR_setgroups32:
5971
        {
5972
            int gidsetsize = arg1;
5973
            uint32_t *target_grouplist;
5974
            gid_t *grouplist;
5975
            int i;
5976

    
5977
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5978
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5979
            if (!target_grouplist) {
5980
                ret = -TARGET_EFAULT;
5981
                goto fail;
5982
            }
5983
            for(i = 0;i < gidsetsize; i++)
5984
                grouplist[i] = tswap32(target_grouplist[i]);
5985
            unlock_user(target_grouplist, arg2, 0);
5986
            ret = get_errno(setgroups(gidsetsize, grouplist));
5987
        }
5988
        break;
5989
#endif
5990
#ifdef TARGET_NR_fchown32
5991
    case TARGET_NR_fchown32:
5992
        ret = get_errno(fchown(arg1, arg2, arg3));
5993
        break;
5994
#endif
5995
#ifdef TARGET_NR_setresuid32
5996
    case TARGET_NR_setresuid32:
5997
        ret = get_errno(setresuid(arg1, arg2, arg3));
5998
        break;
5999
#endif
6000
#ifdef TARGET_NR_getresuid32
6001
    case TARGET_NR_getresuid32:
6002
        {
6003
            uid_t ruid, euid, suid;
6004
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6005
            if (!is_error(ret)) {
6006
                if (put_user_u32(ruid, arg1)
6007
                    || put_user_u32(euid, arg2)
6008
                    || put_user_u32(suid, arg3))
6009
                    goto efault;
6010
            }
6011
        }
6012
        break;
6013
#endif
6014
#ifdef TARGET_NR_setresgid32
6015
    case TARGET_NR_setresgid32:
6016
        ret = get_errno(setresgid(arg1, arg2, arg3));
6017
        break;
6018
#endif
6019
#ifdef TARGET_NR_getresgid32
6020
    case TARGET_NR_getresgid32:
6021
        {
6022
            gid_t rgid, egid, sgid;
6023
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6024
            if (!is_error(ret)) {
6025
                if (put_user_u32(rgid, arg1)
6026
                    || put_user_u32(egid, arg2)
6027
                    || put_user_u32(sgid, arg3))
6028
                    goto efault;
6029
            }
6030
        }
6031
        break;
6032
#endif
6033
#ifdef TARGET_NR_chown32
6034
    case TARGET_NR_chown32:
6035
        if (!(p = lock_user_string(arg1)))
6036
            goto efault;
6037
        ret = get_errno(chown(p, arg2, arg3));
6038
        unlock_user(p, arg1, 0);
6039
        break;
6040
#endif
6041
#ifdef TARGET_NR_setuid32
6042
    case TARGET_NR_setuid32:
6043
        ret = get_errno(setuid(arg1));
6044
        break;
6045
#endif
6046
#ifdef TARGET_NR_setgid32
6047
    case TARGET_NR_setgid32:
6048
        ret = get_errno(setgid(arg1));
6049
        break;
6050
#endif
6051
#ifdef TARGET_NR_setfsuid32
6052
    case TARGET_NR_setfsuid32:
6053
        ret = get_errno(setfsuid(arg1));
6054
        break;
6055
#endif
6056
#ifdef TARGET_NR_setfsgid32
6057
    case TARGET_NR_setfsgid32:
6058
        ret = get_errno(setfsgid(arg1));
6059
        break;
6060
#endif
6061

    
6062
    case TARGET_NR_pivot_root:
6063
        goto unimplemented;
6064
#ifdef TARGET_NR_mincore
6065
    case TARGET_NR_mincore:
6066
        {
6067
            void *a;
6068
            ret = -TARGET_EFAULT;
6069
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6070
                goto efault;
6071
            if (!(p = lock_user_string(arg3)))
6072
                goto mincore_fail;
6073
            ret = get_errno(mincore(a, arg2, p));
6074
            unlock_user(p, arg3, ret);
6075
            mincore_fail:
6076
            unlock_user(a, arg1, 0);
6077
        }
6078
        break;
6079
#endif
6080
#ifdef TARGET_NR_arm_fadvise64_64
6081
    case TARGET_NR_arm_fadvise64_64:
6082
        {
6083
                /*
6084
                 * arm_fadvise64_64 looks like fadvise64_64 but
6085
                 * with different argument order
6086
                 */
6087
                abi_long temp;
6088
                temp = arg3;
6089
                arg3 = arg4;
6090
                arg4 = temp;
6091
        }
6092
#endif
6093
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6094
#ifdef TARGET_NR_fadvise64_64
6095
    case TARGET_NR_fadvise64_64:
6096
#endif
6097
        /* This is a hint, so ignoring and returning success is ok.  */
6098
        ret = get_errno(0);
6099
        break;
6100
#endif
6101
#ifdef TARGET_NR_madvise
6102
    case TARGET_NR_madvise:
6103
        /* A straight passthrough may not be safe because qemu sometimes
6104
           turns private flie-backed mappings into anonymous mappings.
6105
           This will break MADV_DONTNEED.
6106
           This is a hint, so ignoring and returning success is ok.  */
6107
        ret = get_errno(0);
6108
        break;
6109
#endif
6110
#if TARGET_ABI_BITS == 32
6111
    case TARGET_NR_fcntl64:
6112
    {
6113
        int cmd;
6114
        struct flock64 fl;
6115
        struct target_flock64 *target_fl;
6116
#ifdef TARGET_ARM
6117
        struct target_eabi_flock64 *target_efl;
6118
#endif
6119

    
6120
        switch(arg2){
6121
        case TARGET_F_GETLK64:
6122
            cmd = F_GETLK64;
6123
            break;
6124
        case TARGET_F_SETLK64:
6125
            cmd = F_SETLK64;
6126
            break;
6127
        case TARGET_F_SETLKW64:
6128
            cmd = F_SETLK64;
6129
            break;
6130
        default:
6131
            cmd = arg2;
6132
            break;
6133
        }
6134

    
6135
        switch(arg2) {
6136
        case TARGET_F_GETLK64:
6137
#ifdef TARGET_ARM
6138
            if (((CPUARMState *)cpu_env)->eabi) {
6139
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6140
                    goto efault;
6141
                fl.l_type = tswap16(target_efl->l_type);
6142
                fl.l_whence = tswap16(target_efl->l_whence);
6143
                fl.l_start = tswap64(target_efl->l_start);
6144
                fl.l_len = tswap64(target_efl->l_len);
6145
                fl.l_pid = tswapl(target_efl->l_pid);
6146
                unlock_user_struct(target_efl, arg3, 0);
6147
            } else
6148
#endif
6149
            {
6150
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6151
                    goto efault;
6152
                fl.l_type = tswap16(target_fl->l_type);
6153
                fl.l_whence = tswap16(target_fl->l_whence);
6154
                fl.l_start = tswap64(target_fl->l_start);
6155
                fl.l_len = tswap64(target_fl->l_len);
6156
                fl.l_pid = tswapl(target_fl->l_pid);
6157
                unlock_user_struct(target_fl, arg3, 0);
6158
            }
6159
            ret = get_errno(fcntl(arg1, cmd, &fl));
6160
            if (ret == 0) {
6161
#ifdef TARGET_ARM
6162
                if (((CPUARMState *)cpu_env)->eabi) {
6163
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6164
                        goto efault;
6165
                    target_efl->l_type = tswap16(fl.l_type);
6166
                    target_efl->l_whence = tswap16(fl.l_whence);
6167
                    target_efl->l_start = tswap64(fl.l_start);
6168
                    target_efl->l_len = tswap64(fl.l_len);
6169
                    target_efl->l_pid = tswapl(fl.l_pid);
6170
                    unlock_user_struct(target_efl, arg3, 1);
6171
                } else
6172
#endif
6173
                {
6174
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6175
                        goto efault;
6176
                    target_fl->l_type = tswap16(fl.l_type);
6177
                    target_fl->l_whence = tswap16(fl.l_whence);
6178
                    target_fl->l_start = tswap64(fl.l_start);
6179
                    target_fl->l_len = tswap64(fl.l_len);
6180
                    target_fl->l_pid = tswapl(fl.l_pid);
6181
                    unlock_user_struct(target_fl, arg3, 1);
6182
                }
6183
            }
6184
            break;
6185

    
6186
        case TARGET_F_SETLK64:
6187
        case TARGET_F_SETLKW64:
6188
#ifdef TARGET_ARM
6189
            if (((CPUARMState *)cpu_env)->eabi) {
6190
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6191
                    goto efault;
6192
                fl.l_type = tswap16(target_efl->l_type);
6193
                fl.l_whence = tswap16(target_efl->l_whence);
6194
                fl.l_start = tswap64(target_efl->l_start);
6195
                fl.l_len = tswap64(target_efl->l_len);
6196
                fl.l_pid = tswapl(target_efl->l_pid);
6197
                unlock_user_struct(target_efl, arg3, 0);
6198
            } else
6199
#endif
6200
            {
6201
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6202
                    goto efault;
6203
                fl.l_type = tswap16(target_fl->l_type);
6204
                fl.l_whence = tswap16(target_fl->l_whence);
6205
                fl.l_start = tswap64(target_fl->l_start);
6206
                fl.l_len = tswap64(target_fl->l_len);
6207
                fl.l_pid = tswapl(target_fl->l_pid);
6208
                unlock_user_struct(target_fl, arg3, 0);
6209
            }
6210
            ret = get_errno(fcntl(arg1, cmd, &fl));
6211
            break;
6212
        default:
6213
            ret = do_fcntl(arg1, cmd, arg3);
6214
            break;
6215
        }
6216
        break;
6217
    }
6218
#endif
6219
#ifdef TARGET_NR_cacheflush
6220
    case TARGET_NR_cacheflush:
6221
        /* self-modifying code is handled automatically, so nothing needed */
6222
        ret = 0;
6223
        break;
6224
#endif
6225
#ifdef TARGET_NR_security
6226
    case TARGET_NR_security:
6227
        goto unimplemented;
6228
#endif
6229
#ifdef TARGET_NR_getpagesize
6230
    case TARGET_NR_getpagesize:
6231
        ret = TARGET_PAGE_SIZE;
6232
        break;
6233
#endif
6234
    case TARGET_NR_gettid:
6235
        ret = get_errno(gettid());
6236
        break;
6237
#ifdef TARGET_NR_readahead
6238
    case TARGET_NR_readahead:
6239
#if TARGET_ABI_BITS == 32
6240
#ifdef TARGET_ARM
6241
        if (((CPUARMState *)cpu_env)->eabi)
6242
        {
6243
            arg2 = arg3;
6244
            arg3 = arg4;
6245
            arg4 = arg5;
6246
        }
6247
#endif
6248
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6249
#else
6250
        ret = get_errno(readahead(arg1, arg2, arg3));
6251
#endif
6252
        break;
6253
#endif
6254
#ifdef TARGET_NR_setxattr
6255
    case TARGET_NR_setxattr:
6256
    case TARGET_NR_lsetxattr:
6257
    case TARGET_NR_fsetxattr:
6258
    case TARGET_NR_getxattr:
6259
    case TARGET_NR_lgetxattr:
6260
    case TARGET_NR_fgetxattr:
6261
    case TARGET_NR_listxattr:
6262
    case TARGET_NR_llistxattr:
6263
    case TARGET_NR_flistxattr:
6264
    case TARGET_NR_removexattr:
6265
    case TARGET_NR_lremovexattr:
6266
    case TARGET_NR_fremovexattr:
6267
        goto unimplemented_nowarn;
6268
#endif
6269
#ifdef TARGET_NR_set_thread_area
6270
    case TARGET_NR_set_thread_area:
6271
#if defined(TARGET_MIPS)
6272
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6273
      ret = 0;
6274
      break;
6275
#elif defined(TARGET_CRIS)
6276
      if (arg1 & 0xff)
6277
          ret = -TARGET_EINVAL;
6278
      else {
6279
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6280
          ret = 0;
6281
      }
6282
      break;
6283
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6284
      ret = do_set_thread_area(cpu_env, arg1);
6285
      break;
6286
#else
6287
      goto unimplemented_nowarn;
6288
#endif
6289
#endif
6290
#ifdef TARGET_NR_get_thread_area
6291
    case TARGET_NR_get_thread_area:
6292
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6293
        ret = do_get_thread_area(cpu_env, arg1);
6294
#else
6295
        goto unimplemented_nowarn;
6296
#endif
6297
#endif
6298
#ifdef TARGET_NR_getdomainname
6299
    case TARGET_NR_getdomainname:
6300
        goto unimplemented_nowarn;
6301
#endif
6302

    
6303
#ifdef TARGET_NR_clock_gettime
6304
    case TARGET_NR_clock_gettime:
6305
    {
6306
        struct timespec ts;
6307
        ret = get_errno(clock_gettime(arg1, &ts));
6308
        if (!is_error(ret)) {
6309
            host_to_target_timespec(arg2, &ts);
6310
        }
6311
        break;
6312
    }
6313
#endif
6314
#ifdef TARGET_NR_clock_getres
6315
    case TARGET_NR_clock_getres:
6316
    {
6317
        struct timespec ts;
6318
        ret = get_errno(clock_getres(arg1, &ts));
6319
        if (!is_error(ret)) {
6320
            host_to_target_timespec(arg2, &ts);
6321
        }
6322
        break;
6323
    }
6324
#endif
6325
#ifdef TARGET_NR_clock_nanosleep
6326
    case TARGET_NR_clock_nanosleep:
6327
    {
6328
        struct timespec ts;
6329
        target_to_host_timespec(&ts, arg3);
6330
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6331
        if (arg4)
6332
            host_to_target_timespec(arg4, &ts);
6333
        break;
6334
    }
6335
#endif
6336

    
6337
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6338
    case TARGET_NR_set_tid_address:
6339
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6340
        break;
6341
#endif
6342

    
6343
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6344
    case TARGET_NR_tkill:
6345
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6346
        break;
6347
#endif
6348

    
6349
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6350
    case TARGET_NR_tgkill:
6351
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6352
                        target_to_host_signal(arg3)));
6353
        break;
6354
#endif
6355

    
6356
#ifdef TARGET_NR_set_robust_list
6357
    case TARGET_NR_set_robust_list:
6358
        goto unimplemented_nowarn;
6359
#endif
6360

    
6361
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6362
    case TARGET_NR_utimensat:
6363
        {
6364
            struct timespec ts[2];
6365
            target_to_host_timespec(ts, arg3);
6366
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6367
            if (!arg2)
6368
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6369
            else {
6370
                if (!(p = lock_user_string(arg2))) {
6371
                    ret = -TARGET_EFAULT;
6372
                    goto fail;
6373
                }
6374
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6375
                unlock_user(p, arg2, 0);
6376
            }
6377
        }
6378
        break;
6379
#endif
6380
#if defined(USE_NPTL)
6381
    case TARGET_NR_futex:
6382
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6383
        break;
6384
#endif
6385
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6386
    case TARGET_NR_inotify_init:
6387
        ret = get_errno(sys_inotify_init());
6388
        break;
6389
#endif
6390
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6391
    case TARGET_NR_inotify_add_watch:
6392
        p = lock_user_string(arg2);
6393
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6394
        unlock_user(p, arg2, 0);
6395
        break;
6396
#endif
6397
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6398
    case TARGET_NR_inotify_rm_watch:
6399
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6400
        break;
6401
#endif
6402

    
6403
#ifdef TARGET_NR_mq_open
6404
    case TARGET_NR_mq_open:
6405
        {
6406
            struct mq_attr posix_mq_attr;
6407

    
6408
            p = lock_user_string(arg1 - 1);
6409
            if (arg4 != 0)
6410
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6411
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6412
            unlock_user (p, arg1, 0);
6413
        }
6414
        break;
6415

    
6416
    case TARGET_NR_mq_unlink:
6417
        p = lock_user_string(arg1 - 1);
6418
        ret = get_errno(mq_unlink(p));
6419
        unlock_user (p, arg1, 0);
6420
        break;
6421

    
6422
    case TARGET_NR_mq_timedsend:
6423
        {
6424
            struct timespec ts;
6425

    
6426
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6427
            if (arg5 != 0) {
6428
                target_to_host_timespec(&ts, arg5);
6429
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6430
                host_to_target_timespec(arg5, &ts);
6431
            }
6432
            else
6433
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6434
            unlock_user (p, arg2, arg3);
6435
        }
6436
        break;
6437

    
6438
    case TARGET_NR_mq_timedreceive:
6439
        {
6440
            struct timespec ts;
6441
            unsigned int prio;
6442

    
6443
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6444
            if (arg5 != 0) {
6445
                target_to_host_timespec(&ts, arg5);
6446
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6447
                host_to_target_timespec(arg5, &ts);
6448
            }
6449
            else
6450
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6451
            unlock_user (p, arg2, arg3);
6452
            if (arg4 != 0)
6453
                put_user_u32(prio, arg4);
6454
        }
6455
        break;
6456

    
6457
    /* Not implemented for now... */
6458
/*     case TARGET_NR_mq_notify: */
6459
/*         break; */
6460

    
6461
    case TARGET_NR_mq_getsetattr:
6462
        {
6463
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6464
            ret = 0;
6465
            if (arg3 != 0) {
6466
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6467
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6468
            }
6469
            if (arg2 != 0) {
6470
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6471
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6472
            }
6473

    
6474
        }
6475
        break;
6476
#endif
6477

    
6478
    default:
6479
    unimplemented:
6480
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6481
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6482
    unimplemented_nowarn:
6483
#endif
6484
        ret = -TARGET_ENOSYS;
6485
        break;
6486
    }
6487
fail:
6488
#ifdef DEBUG
6489
    gemu_log(" = %ld\n", ret);
6490
#endif
6491
    if(do_strace)
6492
        print_syscall_ret(num, ret);
6493
    return ret;
6494
efault:
6495
    ret = -TARGET_EFAULT;
6496
    goto fail;
6497
}