Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 6f932f91

History | View | Annotate | Download (208.4 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
//#include <linux/msdos_fs.h>
97
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
98
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
99

    
100

    
101
#undef _syscall0
102
#undef _syscall1
103
#undef _syscall2
104
#undef _syscall3
105
#undef _syscall4
106
#undef _syscall5
107
#undef _syscall6
108

    
109
#define _syscall0(type,name)                \
110
static type name (void)                        \
111
{                                        \
112
        return syscall(__NR_##name);        \
113
}
114

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

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

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

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

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

    
146

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

    
155

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

    
185
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
186
#define __NR__llseek __NR_lseek
187
#endif
188

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

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

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

    
257
static int sys_uname(struct new_utsname *buf)
258
{
259
  struct utsname uts_buf;
260

    
261
  if (uname(&uts_buf) < 0)
262
      return (-1);
263

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

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

    
281
#undef COPY_UTSNAME_FIELD
282
}
283

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

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

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

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

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

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

    
468
#endif /* CONFIG_ATFILE */
469

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

    
486
#ifdef CONFIG_INOTIFY
487
#include <sys/inotify.h>
488

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

    
514

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

    
521
#define ERRNO_TABLE_SIZE 1200
522

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

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

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

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

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

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

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

    
672
static abi_ulong target_brk;
673
static abi_ulong target_original_brk;
674

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

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

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

    
692
    brk_page = HOST_PAGE_ALIGN(target_brk);
693

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

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

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

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

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

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

    
739
    unlock_user(target_fds, target_fds_addr, 0);
740

    
741
    return 0;
742
}
743

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

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

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

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

    
771
    return 0;
772
}
773

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

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

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

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

    
816
    return 0;
817
}
818

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

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

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

    
830
    unlock_user_struct(target_tv, target_tv_addr, 0);
831

    
832
    return 0;
833
}
834

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

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

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

    
846
    unlock_user_struct(target_tv, target_tv_addr, 1);
847

    
848
    return 0;
849
}
850

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

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

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

    
865
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
866

    
867
    return 0;
868
}
869

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

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

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

    
884
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
885

    
886
    return 0;
887
}
888

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

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

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

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

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

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

    
943
    return ret;
944
}
945

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

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

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

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

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

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

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

    
983
    return 0;
984
}
985

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

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

    
999
    return 0;
1000
}
1001

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1389
    return 0;
1390
}
1391

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

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

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

    
1431
    addr = alloca(addrlen+1);
1432

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

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

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

    
1446
    addr = alloca(addrlen);
1447

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

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

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

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

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

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

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

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

    
1521
    addr = alloca(addrlen);
1522

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

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

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

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

    
1546
    addr = alloca(addrlen);
1547

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

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

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

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

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

    
1574
    addr = alloca(addrlen);
1575

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1926
#define N_SHM_REGIONS        32
1927

    
1928
static struct shm_region {
1929
    abi_ulong        start;
1930
    abi_ulong        size;
1931
} shm_regions[N_SHM_REGIONS];
1932

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

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

    
1960
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1961
                                               abi_ulong target_addr)
1962
{
1963
    struct target_ipc_perm *target_ip;
1964
    struct target_semid_ds *target_sd;
1965

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

    
1979
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1980
                                               struct ipc_perm *host_ip)
1981
{
1982
    struct target_ipc_perm *target_ip;
1983
    struct target_semid_ds *target_sd;
1984

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

    
1998
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1999
                                               abi_ulong target_addr)
2000
{
2001
    struct target_semid_ds *target_sd;
2002

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

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

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

    
2030
struct target_seminfo {
2031
    int semmap;
2032
    int semmni;
2033
    int semmns;
2034
    int semmnu;
2035
    int semmsl;
2036
    int semopm;
2037
    int semume;
2038
    int semusz;
2039
    int semvmx;
2040
    int semaem;
2041
};
2042

    
2043
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2044
                                              struct seminfo *host_seminfo)
2045
{
2046
    struct target_seminfo *target_seminfo;
2047
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2048
        return -TARGET_EFAULT;
2049
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2050
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2051
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2052
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2053
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2054
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2055
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2056
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2057
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2058
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2059
    unlock_user_struct(target_seminfo, target_addr, 1);
2060
    return 0;
2061
}
2062

    
2063
union semun {
2064
        int val;
2065
        struct semid_ds *buf;
2066
        unsigned short *array;
2067
        struct seminfo *__buf;
2068
};
2069

    
2070
union target_semun {
2071
        int val;
2072
        abi_ulong buf;
2073
        abi_ulong array;
2074
        abi_ulong __buf;
2075
};
2076

    
2077
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2078
                                               abi_ulong target_addr)
2079
{
2080
    int nsems;
2081
    unsigned short *array;
2082
    union semun semun;
2083
    struct semid_ds semid_ds;
2084
    int i, ret;
2085

    
2086
    semun.buf = &semid_ds;
2087

    
2088
    ret = semctl(semid, 0, IPC_STAT, semun);
2089
    if (ret == -1)
2090
        return get_errno(ret);
2091

    
2092
    nsems = semid_ds.sem_nsems;
2093

    
2094
    *host_array = malloc(nsems*sizeof(unsigned short));
2095
    array = lock_user(VERIFY_READ, target_addr,
2096
                      nsems*sizeof(unsigned short), 1);
2097
    if (!array)
2098
        return -TARGET_EFAULT;
2099

    
2100
    for(i=0; i<nsems; i++) {
2101
        __get_user((*host_array)[i], &array[i]);
2102
    }
2103
    unlock_user(array, target_addr, 0);
2104

    
2105
    return 0;
2106
}
2107

    
2108
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2109
                                               unsigned short **host_array)
2110
{
2111
    int nsems;
2112
    unsigned short *array;
2113
    union semun semun;
2114
    struct semid_ds semid_ds;
2115
    int i, ret;
2116

    
2117
    semun.buf = &semid_ds;
2118

    
2119
    ret = semctl(semid, 0, IPC_STAT, semun);
2120
    if (ret == -1)
2121
        return get_errno(ret);
2122

    
2123
    nsems = semid_ds.sem_nsems;
2124

    
2125
    array = lock_user(VERIFY_WRITE, target_addr,
2126
                      nsems*sizeof(unsigned short), 0);
2127
    if (!array)
2128
        return -TARGET_EFAULT;
2129

    
2130
    for(i=0; i<nsems; i++) {
2131
        __put_user((*host_array)[i], &array[i]);
2132
    }
2133
    free(*host_array);
2134
    unlock_user(array, target_addr, 1);
2135

    
2136
    return 0;
2137
}
2138

    
2139
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2140
                                 union target_semun target_su)
2141
{
2142
    union semun arg;
2143
    struct semid_ds dsarg;
2144
    unsigned short *array;
2145
    struct seminfo seminfo;
2146
    abi_long ret = -TARGET_EINVAL;
2147
    abi_long err;
2148
    cmd &= 0xff;
2149

    
2150
    switch( cmd ) {
2151
        case GETVAL:
2152
        case SETVAL:
2153
            arg.val = tswapl(target_su.val);
2154
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2155
            target_su.val = tswapl(arg.val);
2156
            break;
2157
        case GETALL:
2158
        case SETALL:
2159
            err = target_to_host_semarray(semid, &array, target_su.array);
2160
            if (err)
2161
                return err;
2162
            arg.array = array;
2163
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2164
            err = host_to_target_semarray(semid, target_su.array, &array);
2165
            if (err)
2166
                return err;
2167
            break;
2168
        case IPC_STAT:
2169
        case IPC_SET:
2170
        case SEM_STAT:
2171
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2172
            if (err)
2173
                return err;
2174
            arg.buf = &dsarg;
2175
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2176
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2177
            if (err)
2178
                return err;
2179
            break;
2180
        case IPC_INFO:
2181
        case SEM_INFO:
2182
            arg.__buf = &seminfo;
2183
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2184
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2185
            if (err)
2186
                return err;
2187
            break;
2188
        case IPC_RMID:
2189
        case GETPID:
2190
        case GETNCNT:
2191
        case GETZCNT:
2192
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2193
            break;
2194
    }
2195

    
2196
    return ret;
2197
}
2198

    
2199
struct target_sembuf {
2200
    unsigned short sem_num;
2201
    short sem_op;
2202
    short sem_flg;
2203
};
2204

    
2205
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2206
                                             abi_ulong target_addr,
2207
                                             unsigned nsops)
2208
{
2209
    struct target_sembuf *target_sembuf;
2210
    int i;
2211

    
2212
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2213
                              nsops*sizeof(struct target_sembuf), 1);
2214
    if (!target_sembuf)
2215
        return -TARGET_EFAULT;
2216

    
2217
    for(i=0; i<nsops; i++) {
2218
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2219
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2220
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2221
    }
2222

    
2223
    unlock_user(target_sembuf, target_addr, 0);
2224

    
2225
    return 0;
2226
}
2227

    
2228
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2229
{
2230
    struct sembuf sops[nsops];
2231

    
2232
    if (target_to_host_sembuf(sops, ptr, nsops))
2233
        return -TARGET_EFAULT;
2234

    
2235
    return semop(semid, sops, nsops);
2236
}
2237

    
2238
struct target_msqid_ds
2239
{
2240
    struct target_ipc_perm msg_perm;
2241
    abi_ulong msg_stime;
2242
#if TARGET_ABI_BITS == 32
2243
    abi_ulong __unused1;
2244
#endif
2245
    abi_ulong msg_rtime;
2246
#if TARGET_ABI_BITS == 32
2247
    abi_ulong __unused2;
2248
#endif
2249
    abi_ulong msg_ctime;
2250
#if TARGET_ABI_BITS == 32
2251
    abi_ulong __unused3;
2252
#endif
2253
    abi_ulong __msg_cbytes;
2254
    abi_ulong msg_qnum;
2255
    abi_ulong msg_qbytes;
2256
    abi_ulong msg_lspid;
2257
    abi_ulong msg_lrpid;
2258
    abi_ulong __unused4;
2259
    abi_ulong __unused5;
2260
};
2261

    
2262
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2263
                                               abi_ulong target_addr)
2264
{
2265
    struct target_msqid_ds *target_md;
2266

    
2267
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2268
        return -TARGET_EFAULT;
2269
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2270
        return -TARGET_EFAULT;
2271
    host_md->msg_stime = tswapl(target_md->msg_stime);
2272
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2273
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2274
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2275
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2276
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2277
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2278
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2279
    unlock_user_struct(target_md, target_addr, 0);
2280
    return 0;
2281
}
2282

    
2283
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2284
                                               struct msqid_ds *host_md)
2285
{
2286
    struct target_msqid_ds *target_md;
2287

    
2288
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2289
        return -TARGET_EFAULT;
2290
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2291
        return -TARGET_EFAULT;
2292
    target_md->msg_stime = tswapl(host_md->msg_stime);
2293
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2294
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2295
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2296
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2297
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2298
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2299
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2300
    unlock_user_struct(target_md, target_addr, 1);
2301
    return 0;
2302
}
2303

    
2304
struct target_msginfo {
2305
    int msgpool;
2306
    int msgmap;
2307
    int msgmax;
2308
    int msgmnb;
2309
    int msgmni;
2310
    int msgssz;
2311
    int msgtql;
2312
    unsigned short int msgseg;
2313
};
2314

    
2315
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2316
                                              struct msginfo *host_msginfo)
2317
{
2318
    struct target_msginfo *target_msginfo;
2319
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2320
        return -TARGET_EFAULT;
2321
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2322
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2323
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2324
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2325
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2326
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2327
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2328
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2329
    unlock_user_struct(target_msginfo, target_addr, 1);
2330
    return 0;
2331
}
2332

    
2333
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2334
{
2335
    struct msqid_ds dsarg;
2336
    struct msginfo msginfo;
2337
    abi_long ret = -TARGET_EINVAL;
2338

    
2339
    cmd &= 0xff;
2340

    
2341
    switch (cmd) {
2342
    case IPC_STAT:
2343
    case IPC_SET:
2344
    case MSG_STAT:
2345
        if (target_to_host_msqid_ds(&dsarg,ptr))
2346
            return -TARGET_EFAULT;
2347
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2348
        if (host_to_target_msqid_ds(ptr,&dsarg))
2349
            return -TARGET_EFAULT;
2350
        break;
2351
    case IPC_RMID:
2352
        ret = get_errno(msgctl(msgid, cmd, NULL));
2353
        break;
2354
    case IPC_INFO:
2355
    case MSG_INFO:
2356
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2357
        if (host_to_target_msginfo(ptr, &msginfo))
2358
            return -TARGET_EFAULT;
2359
        break;
2360
    }
2361

    
2362
    return ret;
2363
}
2364

    
2365
struct target_msgbuf {
2366
    abi_long mtype;
2367
    char        mtext[1];
2368
};
2369

    
2370
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2371
                                 unsigned int msgsz, int msgflg)
2372
{
2373
    struct target_msgbuf *target_mb;
2374
    struct msgbuf *host_mb;
2375
    abi_long ret = 0;
2376

    
2377
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2378
        return -TARGET_EFAULT;
2379
    host_mb = malloc(msgsz+sizeof(long));
2380
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2381
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2382
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2383
    free(host_mb);
2384
    unlock_user_struct(target_mb, msgp, 0);
2385

    
2386
    return ret;
2387
}
2388

    
2389
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2390
                                 unsigned int msgsz, abi_long msgtyp,
2391
                                 int msgflg)
2392
{
2393
    struct target_msgbuf *target_mb;
2394
    char *target_mtext;
2395
    struct msgbuf *host_mb;
2396
    abi_long ret = 0;
2397

    
2398
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2399
        return -TARGET_EFAULT;
2400

    
2401
    host_mb = malloc(msgsz+sizeof(long));
2402
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2403

    
2404
    if (ret > 0) {
2405
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2406
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2407
        if (!target_mtext) {
2408
            ret = -TARGET_EFAULT;
2409
            goto end;
2410
        }
2411
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2412
        unlock_user(target_mtext, target_mtext_addr, ret);
2413
    }
2414

    
2415
    target_mb->mtype = tswapl(host_mb->mtype);
2416
    free(host_mb);
2417

    
2418
end:
2419
    if (target_mb)
2420
        unlock_user_struct(target_mb, msgp, 1);
2421
    return ret;
2422
}
2423

    
2424
struct target_shmid_ds
2425
{
2426
    struct target_ipc_perm shm_perm;
2427
    abi_ulong shm_segsz;
2428
    abi_ulong shm_atime;
2429
#if TARGET_ABI_BITS == 32
2430
    abi_ulong __unused1;
2431
#endif
2432
    abi_ulong shm_dtime;
2433
#if TARGET_ABI_BITS == 32
2434
    abi_ulong __unused2;
2435
#endif
2436
    abi_ulong shm_ctime;
2437
#if TARGET_ABI_BITS == 32
2438
    abi_ulong __unused3;
2439
#endif
2440
    int shm_cpid;
2441
    int shm_lpid;
2442
    abi_ulong shm_nattch;
2443
    unsigned long int __unused4;
2444
    unsigned long int __unused5;
2445
};
2446

    
2447
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2448
                                               abi_ulong target_addr)
2449
{
2450
    struct target_shmid_ds *target_sd;
2451

    
2452
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2453
        return -TARGET_EFAULT;
2454
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2455
        return -TARGET_EFAULT;
2456
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2457
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2458
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2459
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2460
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2461
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2462
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2463
    unlock_user_struct(target_sd, target_addr, 0);
2464
    return 0;
2465
}
2466

    
2467
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2468
                                               struct shmid_ds *host_sd)
2469
{
2470
    struct target_shmid_ds *target_sd;
2471

    
2472
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2473
        return -TARGET_EFAULT;
2474
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2475
        return -TARGET_EFAULT;
2476
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2477
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2478
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2479
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2480
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2481
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2482
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2483
    unlock_user_struct(target_sd, target_addr, 1);
2484
    return 0;
2485
}
2486

    
2487
struct  target_shminfo {
2488
    abi_ulong shmmax;
2489
    abi_ulong shmmin;
2490
    abi_ulong shmmni;
2491
    abi_ulong shmseg;
2492
    abi_ulong shmall;
2493
};
2494

    
2495
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2496
                                              struct shminfo *host_shminfo)
2497
{
2498
    struct target_shminfo *target_shminfo;
2499
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2500
        return -TARGET_EFAULT;
2501
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2502
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2503
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2504
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2505
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2506
    unlock_user_struct(target_shminfo, target_addr, 1);
2507
    return 0;
2508
}
2509

    
2510
struct target_shm_info {
2511
    int used_ids;
2512
    abi_ulong shm_tot;
2513
    abi_ulong shm_rss;
2514
    abi_ulong shm_swp;
2515
    abi_ulong swap_attempts;
2516
    abi_ulong swap_successes;
2517
};
2518

    
2519
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2520
                                               struct shm_info *host_shm_info)
2521
{
2522
    struct target_shm_info *target_shm_info;
2523
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2524
        return -TARGET_EFAULT;
2525
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2526
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2527
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2528
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2529
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2530
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2531
    unlock_user_struct(target_shm_info, target_addr, 1);
2532
    return 0;
2533
}
2534

    
2535
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2536
{
2537
    struct shmid_ds dsarg;
2538
    struct shminfo shminfo;
2539
    struct shm_info shm_info;
2540
    abi_long ret = -TARGET_EINVAL;
2541

    
2542
    cmd &= 0xff;
2543

    
2544
    switch(cmd) {
2545
    case IPC_STAT:
2546
    case IPC_SET:
2547
    case SHM_STAT:
2548
        if (target_to_host_shmid_ds(&dsarg, buf))
2549
            return -TARGET_EFAULT;
2550
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2551
        if (host_to_target_shmid_ds(buf, &dsarg))
2552
            return -TARGET_EFAULT;
2553
        break;
2554
    case IPC_INFO:
2555
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2556
        if (host_to_target_shminfo(buf, &shminfo))
2557
            return -TARGET_EFAULT;
2558
        break;
2559
    case SHM_INFO:
2560
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2561
        if (host_to_target_shm_info(buf, &shm_info))
2562
            return -TARGET_EFAULT;
2563
        break;
2564
    case IPC_RMID:
2565
    case SHM_LOCK:
2566
    case SHM_UNLOCK:
2567
        ret = get_errno(shmctl(shmid, cmd, NULL));
2568
        break;
2569
    }
2570

    
2571
    return ret;
2572
}
2573

    
2574
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2575
{
2576
    abi_long raddr;
2577
    void *host_raddr;
2578
    struct shmid_ds shm_info;
2579
    int i,ret;
2580

    
2581
    /* find out the length of the shared memory segment */
2582
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2583
    if (is_error(ret)) {
2584
        /* can't get length, bail out */
2585
        return ret;
2586
    }
2587

    
2588
    mmap_lock();
2589

    
2590
    if (shmaddr)
2591
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2592
    else {
2593
        abi_ulong mmap_start;
2594

    
2595
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2596

    
2597
        if (mmap_start == -1) {
2598
            errno = ENOMEM;
2599
            host_raddr = (void *)-1;
2600
        } else
2601
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2602
    }
2603

    
2604
    if (host_raddr == (void *)-1) {
2605
        mmap_unlock();
2606
        return get_errno((long)host_raddr);
2607
    }
2608
    raddr=h2g((unsigned long)host_raddr);
2609

    
2610
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2611
                   PAGE_VALID | PAGE_READ |
2612
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2613

    
2614
    for (i = 0; i < N_SHM_REGIONS; i++) {
2615
        if (shm_regions[i].start == 0) {
2616
            shm_regions[i].start = raddr;
2617
            shm_regions[i].size = shm_info.shm_segsz;
2618
            break;
2619
        }
2620
    }
2621

    
2622
    mmap_unlock();
2623
    return raddr;
2624

    
2625
}
2626

    
2627
static inline abi_long do_shmdt(abi_ulong shmaddr)
2628
{
2629
    int i;
2630

    
2631
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2632
        if (shm_regions[i].start == shmaddr) {
2633
            shm_regions[i].start = 0;
2634
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2635
            break;
2636
        }
2637
    }
2638

    
2639
    return get_errno(shmdt(g2h(shmaddr)));
2640
}
2641

    
2642
#ifdef TARGET_NR_ipc
2643
/* ??? This only works with linear mappings.  */
2644
/* do_ipc() must return target values and target errnos. */
2645
static abi_long do_ipc(unsigned int call, int first,
2646
                       int second, int third,
2647
                       abi_long ptr, abi_long fifth)
2648
{
2649
    int version;
2650
    abi_long ret = 0;
2651

    
2652
    version = call >> 16;
2653
    call &= 0xffff;
2654

    
2655
    switch (call) {
2656
    case IPCOP_semop:
2657
        ret = do_semop(first, ptr, second);
2658
        break;
2659

    
2660
    case IPCOP_semget:
2661
        ret = get_errno(semget(first, second, third));
2662
        break;
2663

    
2664
    case IPCOP_semctl:
2665
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2666
        break;
2667

    
2668
    case IPCOP_msgget:
2669
        ret = get_errno(msgget(first, second));
2670
        break;
2671

    
2672
    case IPCOP_msgsnd:
2673
        ret = do_msgsnd(first, ptr, second, third);
2674
        break;
2675

    
2676
    case IPCOP_msgctl:
2677
        ret = do_msgctl(first, second, ptr);
2678
        break;
2679

    
2680
    case IPCOP_msgrcv:
2681
        switch (version) {
2682
        case 0:
2683
            {
2684
                struct target_ipc_kludge {
2685
                    abi_long msgp;
2686
                    abi_long msgtyp;
2687
                } *tmp;
2688

    
2689
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2690
                    ret = -TARGET_EFAULT;
2691
                    break;
2692
                }
2693

    
2694
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2695

    
2696
                unlock_user_struct(tmp, ptr, 0);
2697
                break;
2698
            }
2699
        default:
2700
            ret = do_msgrcv(first, ptr, second, fifth, third);
2701
        }
2702
        break;
2703

    
2704
    case IPCOP_shmat:
2705
        switch (version) {
2706
        default:
2707
        {
2708
            abi_ulong raddr;
2709
            raddr = do_shmat(first, ptr, second);
2710
            if (is_error(raddr))
2711
                return get_errno(raddr);
2712
            if (put_user_ual(raddr, third))
2713
                return -TARGET_EFAULT;
2714
            break;
2715
        }
2716
        case 1:
2717
            ret = -TARGET_EINVAL;
2718
            break;
2719
        }
2720
        break;
2721
    case IPCOP_shmdt:
2722
        ret = do_shmdt(ptr);
2723
        break;
2724

    
2725
    case IPCOP_shmget:
2726
        /* IPC_* flag values are the same on all linux platforms */
2727
        ret = get_errno(shmget(first, second, third));
2728
        break;
2729

    
2730
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2731
    case IPCOP_shmctl:
2732
        ret = do_shmctl(first, second, third);
2733
        break;
2734
    default:
2735
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2736
        ret = -TARGET_ENOSYS;
2737
        break;
2738
    }
2739
    return ret;
2740
}
2741
#endif
2742

    
2743
/* kernel structure types definitions */
2744
#define IFNAMSIZ        16
2745

    
2746
#define STRUCT(name, ...) STRUCT_ ## name,
2747
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2748
enum {
2749
#include "syscall_types.h"
2750
};
2751
#undef STRUCT
2752
#undef STRUCT_SPECIAL
2753

    
2754
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2755
#define STRUCT_SPECIAL(name)
2756
#include "syscall_types.h"
2757
#undef STRUCT
2758
#undef STRUCT_SPECIAL
2759

    
2760
typedef struct IOCTLEntry {
2761
    unsigned int target_cmd;
2762
    unsigned int host_cmd;
2763
    const char *name;
2764
    int access;
2765
    const argtype arg_type[5];
2766
} IOCTLEntry;
2767

    
2768
#define IOC_R 0x0001
2769
#define IOC_W 0x0002
2770
#define IOC_RW (IOC_R | IOC_W)
2771

    
2772
#define MAX_STRUCT_SIZE 4096
2773

    
2774
static IOCTLEntry ioctl_entries[] = {
2775
#define IOCTL(cmd, access, ...) \
2776
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2777
#include "ioctls.h"
2778
    { 0, 0, },
2779
};
2780

    
2781
/* ??? Implement proper locking for ioctls.  */
2782
/* do_ioctl() Must return target values and target errnos. */
2783
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2784
{
2785
    const IOCTLEntry *ie;
2786
    const argtype *arg_type;
2787
    abi_long ret;
2788
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2789
    int target_size;
2790
    void *argptr;
2791

    
2792
    ie = ioctl_entries;
2793
    for(;;) {
2794
        if (ie->target_cmd == 0) {
2795
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2796
            return -TARGET_ENOSYS;
2797
        }
2798
        if (ie->target_cmd == cmd)
2799
            break;
2800
        ie++;
2801
    }
2802
    arg_type = ie->arg_type;
2803
#if defined(DEBUG)
2804
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2805
#endif
2806
    switch(arg_type[0]) {
2807
    case TYPE_NULL:
2808
        /* no argument */
2809
        ret = get_errno(ioctl(fd, ie->host_cmd));
2810
        break;
2811
    case TYPE_PTRVOID:
2812
    case TYPE_INT:
2813
        /* int argment */
2814
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2815
        break;
2816
    case TYPE_PTR:
2817
        arg_type++;
2818
        target_size = thunk_type_size(arg_type, 0);
2819
        switch(ie->access) {
2820
        case IOC_R:
2821
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2822
            if (!is_error(ret)) {
2823
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2824
                if (!argptr)
2825
                    return -TARGET_EFAULT;
2826
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2827
                unlock_user(argptr, arg, target_size);
2828
            }
2829
            break;
2830
        case IOC_W:
2831
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2832
            if (!argptr)
2833
                return -TARGET_EFAULT;
2834
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2835
            unlock_user(argptr, arg, 0);
2836
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2837
            break;
2838
        default:
2839
        case IOC_RW:
2840
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2841
            if (!argptr)
2842
                return -TARGET_EFAULT;
2843
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2844
            unlock_user(argptr, arg, 0);
2845
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2846
            if (!is_error(ret)) {
2847
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2848
                if (!argptr)
2849
                    return -TARGET_EFAULT;
2850
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2851
                unlock_user(argptr, arg, target_size);
2852
            }
2853
            break;
2854
        }
2855
        break;
2856
    default:
2857
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2858
                 (long)cmd, arg_type[0]);
2859
        ret = -TARGET_ENOSYS;
2860
        break;
2861
    }
2862
    return ret;
2863
}
2864

    
2865
static const bitmask_transtbl iflag_tbl[] = {
2866
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2867
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2868
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2869
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2870
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2871
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2872
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2873
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2874
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2875
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2876
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2877
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2878
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2879
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2880
        { 0, 0, 0, 0 }
2881
};
2882

    
2883
static const bitmask_transtbl oflag_tbl[] = {
2884
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2885
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2886
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2887
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2888
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2889
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2890
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2891
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2892
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2893
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2894
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2895
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2896
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2897
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2898
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2899
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2900
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2901
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2902
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2903
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2904
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2905
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2906
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2907
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2908
        { 0, 0, 0, 0 }
2909
};
2910

    
2911
static const bitmask_transtbl cflag_tbl[] = {
2912
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2913
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2914
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2915
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2916
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2917
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2918
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2919
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2920
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2921
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2922
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2923
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2924
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2925
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2926
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2927
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2928
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2929
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2930
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2931
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2932
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2933
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2934
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2935
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2936
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2937
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2938
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2939
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2940
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2941
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2942
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2943
        { 0, 0, 0, 0 }
2944
};
2945

    
2946
static const bitmask_transtbl lflag_tbl[] = {
2947
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2948
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2949
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2950
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2951
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2952
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2953
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2954
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2955
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2956
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2957
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2958
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2959
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2960
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2961
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2962
        { 0, 0, 0, 0 }
2963
};
2964

    
2965
static void target_to_host_termios (void *dst, const void *src)
2966
{
2967
    struct host_termios *host = dst;
2968
    const struct target_termios *target = src;
2969

    
2970
    host->c_iflag =
2971
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2972
    host->c_oflag =
2973
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2974
    host->c_cflag =
2975
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2976
    host->c_lflag =
2977
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2978
    host->c_line = target->c_line;
2979

    
2980
    memset(host->c_cc, 0, sizeof(host->c_cc));
2981
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2982
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2983
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2984
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2985
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2986
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2987
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2988
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2989
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2990
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2991
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2992
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2993
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2994
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2995
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2996
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2997
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2998
}
2999

    
3000
static void host_to_target_termios (void *dst, const void *src)
3001
{
3002
    struct target_termios *target = dst;
3003
    const struct host_termios *host = src;
3004

    
3005
    target->c_iflag =
3006
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3007
    target->c_oflag =
3008
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3009
    target->c_cflag =
3010
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3011
    target->c_lflag =
3012
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3013
    target->c_line = host->c_line;
3014

    
3015
    memset(target->c_cc, 0, sizeof(target->c_cc));
3016
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3017
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3018
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3019
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3020
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3021
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3022
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3023
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3024
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3025
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3026
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3027
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3028
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3029
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3030
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3031
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3032
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3033
}
3034

    
3035
static const StructEntry struct_termios_def = {
3036
    .convert = { host_to_target_termios, target_to_host_termios },
3037
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3038
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3039
};
3040

    
3041
static bitmask_transtbl mmap_flags_tbl[] = {
3042
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3043
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3044
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3045
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3046
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3047
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3048
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3049
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3050
        { 0, 0, 0, 0 }
3051
};
3052

    
3053
#if defined(TARGET_I386)
3054

    
3055
/* NOTE: there is really one LDT for all the threads */
3056
static uint8_t *ldt_table;
3057

    
3058
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3059
{
3060
    int size;
3061
    void *p;
3062

    
3063
    if (!ldt_table)
3064
        return 0;
3065
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3066
    if (size > bytecount)
3067
        size = bytecount;
3068
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3069
    if (!p)
3070
        return -TARGET_EFAULT;
3071
    /* ??? Should this by byteswapped?  */
3072
    memcpy(p, ldt_table, size);
3073
    unlock_user(p, ptr, size);
3074
    return size;
3075
}
3076

    
3077
/* XXX: add locking support */
3078
static abi_long write_ldt(CPUX86State *env,
3079
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3080
{
3081
    struct target_modify_ldt_ldt_s ldt_info;
3082
    struct target_modify_ldt_ldt_s *target_ldt_info;
3083
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3084
    int seg_not_present, useable, lm;
3085
    uint32_t *lp, entry_1, entry_2;
3086

    
3087
    if (bytecount != sizeof(ldt_info))
3088
        return -TARGET_EINVAL;
3089
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3090
        return -TARGET_EFAULT;
3091
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3092
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3093
    ldt_info.limit = tswap32(target_ldt_info->limit);
3094
    ldt_info.flags = tswap32(target_ldt_info->flags);
3095
    unlock_user_struct(target_ldt_info, ptr, 0);
3096

    
3097
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3098
        return -TARGET_EINVAL;
3099
    seg_32bit = ldt_info.flags & 1;
3100
    contents = (ldt_info.flags >> 1) & 3;
3101
    read_exec_only = (ldt_info.flags >> 3) & 1;
3102
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3103
    seg_not_present = (ldt_info.flags >> 5) & 1;
3104
    useable = (ldt_info.flags >> 6) & 1;
3105
#ifdef TARGET_ABI32
3106
    lm = 0;
3107
#else
3108
    lm = (ldt_info.flags >> 7) & 1;
3109
#endif
3110
    if (contents == 3) {
3111
        if (oldmode)
3112
            return -TARGET_EINVAL;
3113
        if (seg_not_present == 0)
3114
            return -TARGET_EINVAL;
3115
    }
3116
    /* allocate the LDT */
3117
    if (!ldt_table) {
3118
        env->ldt.base = target_mmap(0,
3119
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3120
                                    PROT_READ|PROT_WRITE,
3121
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3122
        if (env->ldt.base == -1)
3123
            return -TARGET_ENOMEM;
3124
        memset(g2h(env->ldt.base), 0,
3125
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3126
        env->ldt.limit = 0xffff;
3127
        ldt_table = g2h(env->ldt.base);
3128
    }
3129

    
3130
    /* NOTE: same code as Linux kernel */
3131
    /* Allow LDTs to be cleared by the user. */
3132
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3133
        if (oldmode ||
3134
            (contents == 0                &&
3135
             read_exec_only == 1        &&
3136
             seg_32bit == 0                &&
3137
             limit_in_pages == 0        &&
3138
             seg_not_present == 1        &&
3139
             useable == 0 )) {
3140
            entry_1 = 0;
3141
            entry_2 = 0;
3142
            goto install;
3143
        }
3144
    }
3145

    
3146
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3147
        (ldt_info.limit & 0x0ffff);
3148
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3149
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3150
        (ldt_info.limit & 0xf0000) |
3151
        ((read_exec_only ^ 1) << 9) |
3152
        (contents << 10) |
3153
        ((seg_not_present ^ 1) << 15) |
3154
        (seg_32bit << 22) |
3155
        (limit_in_pages << 23) |
3156
        (lm << 21) |
3157
        0x7000;
3158
    if (!oldmode)
3159
        entry_2 |= (useable << 20);
3160

    
3161
    /* Install the new entry ...  */
3162
install:
3163
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3164
    lp[0] = tswap32(entry_1);
3165
    lp[1] = tswap32(entry_2);
3166
    return 0;
3167
}
3168

    
3169
/* specific and weird i386 syscalls */
3170
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3171
                              unsigned long bytecount)
3172
{
3173
    abi_long ret;
3174

    
3175
    switch (func) {
3176
    case 0:
3177
        ret = read_ldt(ptr, bytecount);
3178
        break;
3179
    case 1:
3180
        ret = write_ldt(env, ptr, bytecount, 1);
3181
        break;
3182
    case 0x11:
3183
        ret = write_ldt(env, ptr, bytecount, 0);
3184
        break;
3185
    default:
3186
        ret = -TARGET_ENOSYS;
3187
        break;
3188
    }
3189
    return ret;
3190
}
3191

    
3192
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3193
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3194
{
3195
    uint64_t *gdt_table = g2h(env->gdt.base);
3196
    struct target_modify_ldt_ldt_s ldt_info;
3197
    struct target_modify_ldt_ldt_s *target_ldt_info;
3198
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3199
    int seg_not_present, useable, lm;
3200
    uint32_t *lp, entry_1, entry_2;
3201
    int i;
3202

    
3203
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3204
    if (!target_ldt_info)
3205
        return -TARGET_EFAULT;
3206
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3207
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3208
    ldt_info.limit = tswap32(target_ldt_info->limit);
3209
    ldt_info.flags = tswap32(target_ldt_info->flags);
3210
    if (ldt_info.entry_number == -1) {
3211
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3212
            if (gdt_table[i] == 0) {
3213
                ldt_info.entry_number = i;
3214
                target_ldt_info->entry_number = tswap32(i);
3215
                break;
3216
            }
3217
        }
3218
    }
3219
    unlock_user_struct(target_ldt_info, ptr, 1);
3220

    
3221
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3222
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3223
           return -TARGET_EINVAL;
3224
    seg_32bit = ldt_info.flags & 1;
3225
    contents = (ldt_info.flags >> 1) & 3;
3226
    read_exec_only = (ldt_info.flags >> 3) & 1;
3227
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3228
    seg_not_present = (ldt_info.flags >> 5) & 1;
3229
    useable = (ldt_info.flags >> 6) & 1;
3230
#ifdef TARGET_ABI32
3231
    lm = 0;
3232
#else
3233
    lm = (ldt_info.flags >> 7) & 1;
3234
#endif
3235

    
3236
    if (contents == 3) {
3237
        if (seg_not_present == 0)
3238
            return -TARGET_EINVAL;
3239
    }
3240

    
3241
    /* NOTE: same code as Linux kernel */
3242
    /* Allow LDTs to be cleared by the user. */
3243
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3244
        if ((contents == 0             &&
3245
             read_exec_only == 1       &&
3246
             seg_32bit == 0            &&
3247
             limit_in_pages == 0       &&
3248
             seg_not_present == 1      &&
3249
             useable == 0 )) {
3250
            entry_1 = 0;
3251
            entry_2 = 0;
3252
            goto install;
3253
        }
3254
    }
3255

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

    
3270
    /* Install the new entry ...  */
3271
install:
3272
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3273
    lp[0] = tswap32(entry_1);
3274
    lp[1] = tswap32(entry_2);
3275
    return 0;
3276
}
3277

    
3278
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3279
{
3280
    struct target_modify_ldt_ldt_s *target_ldt_info;
3281
    uint64_t *gdt_table = g2h(env->gdt.base);
3282
    uint32_t base_addr, limit, flags;
3283
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3284
    int seg_not_present, useable, lm;
3285
    uint32_t *lp, entry_1, entry_2;
3286

    
3287
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3288
    if (!target_ldt_info)
3289
        return -TARGET_EFAULT;
3290
    idx = tswap32(target_ldt_info->entry_number);
3291
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3292
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3293
        unlock_user_struct(target_ldt_info, ptr, 1);
3294
        return -TARGET_EINVAL;
3295
    }
3296
    lp = (uint32_t *)(gdt_table + idx);
3297
    entry_1 = tswap32(lp[0]);
3298
    entry_2 = tswap32(lp[1]);
3299
    
3300
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3301
    contents = (entry_2 >> 10) & 3;
3302
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3303
    seg_32bit = (entry_2 >> 22) & 1;
3304
    limit_in_pages = (entry_2 >> 23) & 1;
3305
    useable = (entry_2 >> 20) & 1;
3306
#ifdef TARGET_ABI32
3307
    lm = 0;
3308
#else
3309
    lm = (entry_2 >> 21) & 1;
3310
#endif
3311
    flags = (seg_32bit << 0) | (contents << 1) |
3312
        (read_exec_only << 3) | (limit_in_pages << 4) |
3313
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3314
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3315
    base_addr = (entry_1 >> 16) | 
3316
        (entry_2 & 0xff000000) | 
3317
        ((entry_2 & 0xff) << 16);
3318
    target_ldt_info->base_addr = tswapl(base_addr);
3319
    target_ldt_info->limit = tswap32(limit);
3320
    target_ldt_info->flags = tswap32(flags);
3321
    unlock_user_struct(target_ldt_info, ptr, 1);
3322
    return 0;
3323
}
3324
#endif /* TARGET_I386 && TARGET_ABI32 */
3325

    
3326
#ifndef TARGET_ABI32
3327
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3328
{
3329
    abi_long ret;
3330
    abi_ulong val;
3331
    int idx;
3332
    
3333
    switch(code) {
3334
    case TARGET_ARCH_SET_GS:
3335
    case TARGET_ARCH_SET_FS:
3336
        if (code == TARGET_ARCH_SET_GS)
3337
            idx = R_GS;
3338
        else
3339
            idx = R_FS;
3340
        cpu_x86_load_seg(env, idx, 0);
3341
        env->segs[idx].base = addr;
3342
        break;
3343
    case TARGET_ARCH_GET_GS:
3344
    case TARGET_ARCH_GET_FS:
3345
        if (code == TARGET_ARCH_GET_GS)
3346
            idx = R_GS;
3347
        else
3348
            idx = R_FS;
3349
        val = env->segs[idx].base;
3350
        if (put_user(val, addr, abi_ulong))
3351
            return -TARGET_EFAULT;
3352
        break;
3353
    default:
3354
        ret = -TARGET_EINVAL;
3355
        break;
3356
    }
3357
    return 0;
3358
}
3359
#endif
3360

    
3361
#endif /* defined(TARGET_I386) */
3362

    
3363
#if defined(USE_NPTL)
3364

    
3365
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3366

    
3367
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3368
typedef struct {
3369
    CPUState *env;
3370
    pthread_mutex_t mutex;
3371
    pthread_cond_t cond;
3372
    pthread_t thread;
3373
    uint32_t tid;
3374
    abi_ulong child_tidptr;
3375
    abi_ulong parent_tidptr;
3376
    sigset_t sigmask;
3377
} new_thread_info;
3378

    
3379
static void *clone_func(void *arg)
3380
{
3381
    new_thread_info *info = arg;
3382
    CPUState *env;
3383
    TaskState *ts;
3384

    
3385
    env = info->env;
3386
    thread_env = env;
3387
    ts = (TaskState *)thread_env->opaque;
3388
    info->tid = gettid();
3389
    env->host_tid = info->tid;
3390
    task_settid(ts);
3391
    if (info->child_tidptr)
3392
        put_user_u32(info->tid, info->child_tidptr);
3393
    if (info->parent_tidptr)
3394
        put_user_u32(info->tid, info->parent_tidptr);
3395
    /* Enable signals.  */
3396
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3397
    /* Signal to the parent that we're ready.  */
3398
    pthread_mutex_lock(&info->mutex);
3399
    pthread_cond_broadcast(&info->cond);
3400
    pthread_mutex_unlock(&info->mutex);
3401
    /* Wait until the parent has finshed initializing the tls state.  */
3402
    pthread_mutex_lock(&clone_lock);
3403
    pthread_mutex_unlock(&clone_lock);
3404
    cpu_loop(env);
3405
    /* never exits */
3406
    return NULL;
3407
}
3408
#else
3409
/* this stack is the equivalent of the kernel stack associated with a
3410
   thread/process */
3411
#define NEW_STACK_SIZE 8192
3412

    
3413
static int clone_func(void *arg)
3414
{
3415
    CPUState *env = arg;
3416
    cpu_loop(env);
3417
    /* never exits */
3418
    return 0;
3419
}
3420
#endif
3421

    
3422
/* do_fork() Must return host values and target errnos (unlike most
3423
   do_*() functions). */
3424
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3425
                   abi_ulong parent_tidptr, target_ulong newtls,
3426
                   abi_ulong child_tidptr)
3427
{
3428
    int ret;
3429
    TaskState *ts;
3430
    uint8_t *new_stack;
3431
    CPUState *new_env;
3432
#if defined(USE_NPTL)
3433
    unsigned int nptl_flags;
3434
    sigset_t sigmask;
3435
#endif
3436

    
3437
    /* Emulate vfork() with fork() */
3438
    if (flags & CLONE_VFORK)
3439
        flags &= ~(CLONE_VFORK | CLONE_VM);
3440

    
3441
    if (flags & CLONE_VM) {
3442
        TaskState *parent_ts = (TaskState *)env->opaque;
3443
#if defined(USE_NPTL)
3444
        new_thread_info info;
3445
        pthread_attr_t attr;
3446
#endif
3447
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3448
        init_task_state(ts);
3449
        new_stack = ts->stack;
3450
        /* we create a new CPU instance. */
3451
        new_env = cpu_copy(env);
3452
        /* Init regs that differ from the parent.  */
3453
        cpu_clone_regs(new_env, newsp);
3454
        new_env->opaque = ts;
3455
        ts->bprm = parent_ts->bprm;
3456
        ts->info = parent_ts->info;
3457
#if defined(USE_NPTL)
3458
        nptl_flags = flags;
3459
        flags &= ~CLONE_NPTL_FLAGS2;
3460

    
3461
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3462
            ts->child_tidptr = child_tidptr;
3463
        }
3464

    
3465
        if (nptl_flags & CLONE_SETTLS)
3466
            cpu_set_tls (new_env, newtls);
3467

    
3468
        /* Grab a mutex so that thread setup appears atomic.  */
3469
        pthread_mutex_lock(&clone_lock);
3470

    
3471
        memset(&info, 0, sizeof(info));
3472
        pthread_mutex_init(&info.mutex, NULL);
3473
        pthread_mutex_lock(&info.mutex);
3474
        pthread_cond_init(&info.cond, NULL);
3475
        info.env = new_env;
3476
        if (nptl_flags & CLONE_CHILD_SETTID)
3477
            info.child_tidptr = child_tidptr;
3478
        if (nptl_flags & CLONE_PARENT_SETTID)
3479
            info.parent_tidptr = parent_tidptr;
3480

    
3481
        ret = pthread_attr_init(&attr);
3482
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3483
        /* It is not safe to deliver signals until the child has finished
3484
           initializing, so temporarily block all signals.  */
3485
        sigfillset(&sigmask);
3486
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3487

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

    
3491
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3492
        pthread_attr_destroy(&attr);
3493
        if (ret == 0) {
3494
            /* Wait for the child to initialize.  */
3495
            pthread_cond_wait(&info.cond, &info.mutex);
3496
            ret = info.tid;
3497
            if (flags & CLONE_PARENT_SETTID)
3498
                put_user_u32(ret, parent_tidptr);
3499
        } else {
3500
            ret = -1;
3501
        }
3502
        pthread_mutex_unlock(&info.mutex);
3503
        pthread_cond_destroy(&info.cond);
3504
        pthread_mutex_destroy(&info.mutex);
3505
        pthread_mutex_unlock(&clone_lock);
3506
#else
3507
        if (flags & CLONE_NPTL_FLAGS2)
3508
            return -EINVAL;
3509
        /* This is probably going to die very quickly, but do it anyway.  */
3510
#ifdef __ia64__
3511
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3512
#else
3513
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3514
#endif
3515
#endif
3516
    } else {
3517
        /* if no CLONE_VM, we consider it is a fork */
3518
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3519
            return -EINVAL;
3520
        fork_start();
3521
        ret = fork();
3522
        if (ret == 0) {
3523
            /* Child Process.  */
3524
            cpu_clone_regs(env, newsp);
3525
            fork_end(1);
3526
#if defined(USE_NPTL)
3527
            /* There is a race condition here.  The parent process could
3528
               theoretically read the TID in the child process before the child
3529
               tid is set.  This would require using either ptrace
3530
               (not implemented) or having *_tidptr to point at a shared memory
3531
               mapping.  We can't repeat the spinlock hack used above because
3532
               the child process gets its own copy of the lock.  */
3533
            if (flags & CLONE_CHILD_SETTID)
3534
                put_user_u32(gettid(), child_tidptr);
3535
            if (flags & CLONE_PARENT_SETTID)
3536
                put_user_u32(gettid(), parent_tidptr);
3537
            ts = (TaskState *)env->opaque;
3538
            if (flags & CLONE_SETTLS)
3539
                cpu_set_tls (env, newtls);
3540
            if (flags & CLONE_CHILD_CLEARTID)
3541
                ts->child_tidptr = child_tidptr;
3542
#endif
3543
        } else {
3544
            fork_end(0);
3545
        }
3546
    }
3547
    return ret;
3548
}
3549

    
3550
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3551
{
3552
    struct flock fl;
3553
    struct target_flock *target_fl;
3554
    struct flock64 fl64;
3555
    struct target_flock64 *target_fl64;
3556
    abi_long ret;
3557

    
3558
    switch(cmd) {
3559
    case TARGET_F_GETLK:
3560
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3561
            return -TARGET_EFAULT;
3562
        fl.l_type = tswap16(target_fl->l_type);
3563
        fl.l_whence = tswap16(target_fl->l_whence);
3564
        fl.l_start = tswapl(target_fl->l_start);
3565
        fl.l_len = tswapl(target_fl->l_len);
3566
        fl.l_pid = tswapl(target_fl->l_pid);
3567
        unlock_user_struct(target_fl, arg, 0);
3568
        ret = get_errno(fcntl(fd, cmd, &fl));
3569
        if (ret == 0) {
3570
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3571
                return -TARGET_EFAULT;
3572
            target_fl->l_type = tswap16(fl.l_type);
3573
            target_fl->l_whence = tswap16(fl.l_whence);
3574
            target_fl->l_start = tswapl(fl.l_start);
3575
            target_fl->l_len = tswapl(fl.l_len);
3576
            target_fl->l_pid = tswapl(fl.l_pid);
3577
            unlock_user_struct(target_fl, arg, 1);
3578
        }
3579
        break;
3580

    
3581
    case TARGET_F_SETLK:
3582
    case TARGET_F_SETLKW:
3583
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3584
            return -TARGET_EFAULT;
3585
        fl.l_type = tswap16(target_fl->l_type);
3586
        fl.l_whence = tswap16(target_fl->l_whence);
3587
        fl.l_start = tswapl(target_fl->l_start);
3588
        fl.l_len = tswapl(target_fl->l_len);
3589
        fl.l_pid = tswapl(target_fl->l_pid);
3590
        unlock_user_struct(target_fl, arg, 0);
3591
        ret = get_errno(fcntl(fd, cmd, &fl));
3592
        break;
3593

    
3594
    case TARGET_F_GETLK64:
3595
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3596
            return -TARGET_EFAULT;
3597
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3598
        fl64.l_whence = tswap16(target_fl64->l_whence);
3599
        fl64.l_start = tswapl(target_fl64->l_start);
3600
        fl64.l_len = tswapl(target_fl64->l_len);
3601
        fl64.l_pid = tswap16(target_fl64->l_pid);
3602
        unlock_user_struct(target_fl64, arg, 0);
3603
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3604
        if (ret == 0) {
3605
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3606
                return -TARGET_EFAULT;
3607
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3608
            target_fl64->l_whence = tswap16(fl64.l_whence);
3609
            target_fl64->l_start = tswapl(fl64.l_start);
3610
            target_fl64->l_len = tswapl(fl64.l_len);
3611
            target_fl64->l_pid = tswapl(fl64.l_pid);
3612
            unlock_user_struct(target_fl64, arg, 1);
3613
        }
3614
        break;
3615
    case TARGET_F_SETLK64:
3616
    case TARGET_F_SETLKW64:
3617
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3618
            return -TARGET_EFAULT;
3619
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3620
        fl64.l_whence = tswap16(target_fl64->l_whence);
3621
        fl64.l_start = tswapl(target_fl64->l_start);
3622
        fl64.l_len = tswapl(target_fl64->l_len);
3623
        fl64.l_pid = tswap16(target_fl64->l_pid);
3624
        unlock_user_struct(target_fl64, arg, 0);
3625
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3626
        break;
3627

    
3628
    case F_GETFL:
3629
        ret = get_errno(fcntl(fd, cmd, arg));
3630
        if (ret >= 0) {
3631
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3632
        }
3633
        break;
3634

    
3635
    case F_SETFL:
3636
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3637
        break;
3638

    
3639
    default:
3640
        ret = get_errno(fcntl(fd, cmd, arg));
3641
        break;
3642
    }
3643
    return ret;
3644
}
3645

    
3646
#ifdef USE_UID16
3647

    
3648
static inline int high2lowuid(int uid)
3649
{
3650
    if (uid > 65535)
3651
        return 65534;
3652
    else
3653
        return uid;
3654
}
3655

    
3656
static inline int high2lowgid(int gid)
3657
{
3658
    if (gid > 65535)
3659
        return 65534;
3660
    else
3661
        return gid;
3662
}
3663

    
3664
static inline int low2highuid(int uid)
3665
{
3666
    if ((int16_t)uid == -1)
3667
        return -1;
3668
    else
3669
        return uid;
3670
}
3671

    
3672
static inline int low2highgid(int gid)
3673
{
3674
    if ((int16_t)gid == -1)
3675
        return -1;
3676
    else
3677
        return gid;
3678
}
3679

    
3680
#endif /* USE_UID16 */
3681

    
3682
void syscall_init(void)
3683
{
3684
    IOCTLEntry *ie;
3685
    const argtype *arg_type;
3686
    int size;
3687
    int i;
3688

    
3689
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3690
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3691
#include "syscall_types.h"
3692
#undef STRUCT
3693
#undef STRUCT_SPECIAL
3694

    
3695
    /* we patch the ioctl size if necessary. We rely on the fact that
3696
       no ioctl has all the bits at '1' in the size field */
3697
    ie = ioctl_entries;
3698
    while (ie->target_cmd != 0) {
3699
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3700
            TARGET_IOC_SIZEMASK) {
3701
            arg_type = ie->arg_type;
3702
            if (arg_type[0] != TYPE_PTR) {
3703
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3704
                        ie->target_cmd);
3705
                exit(1);
3706
            }
3707
            arg_type++;
3708
            size = thunk_type_size(arg_type, 0);
3709
            ie->target_cmd = (ie->target_cmd &
3710
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3711
                (size << TARGET_IOC_SIZESHIFT);
3712
        }
3713

    
3714
        /* Build target_to_host_errno_table[] table from
3715
         * host_to_target_errno_table[]. */
3716
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3717
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3718

    
3719
        /* automatic consistency check if same arch */
3720
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3721
    (defined(__x86_64__) && defined(TARGET_X86_64))
3722
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3723
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3724
                    ie->name, ie->target_cmd, ie->host_cmd);
3725
        }
3726
#endif
3727
        ie++;
3728
    }
3729
}
3730

    
3731
#if TARGET_ABI_BITS == 32
3732
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3733
{
3734
#ifdef TARGET_WORDS_BIGENDIAN
3735
    return ((uint64_t)word0 << 32) | word1;
3736
#else
3737
    return ((uint64_t)word1 << 32) | word0;
3738
#endif
3739
}
3740
#else /* TARGET_ABI_BITS == 32 */
3741
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3742
{
3743
    return word0;
3744
}
3745
#endif /* TARGET_ABI_BITS != 32 */
3746

    
3747
#ifdef TARGET_NR_truncate64
3748
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3749
                                         abi_long arg2,
3750
                                         abi_long arg3,
3751
                                         abi_long arg4)
3752
{
3753
#ifdef TARGET_ARM
3754
    if (((CPUARMState *)cpu_env)->eabi)
3755
      {
3756
        arg2 = arg3;
3757
        arg3 = arg4;
3758
      }
3759
#endif
3760
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3761
}
3762
#endif
3763

    
3764
#ifdef TARGET_NR_ftruncate64
3765
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3766
                                          abi_long arg2,
3767
                                          abi_long arg3,
3768
                                          abi_long arg4)
3769
{
3770
#ifdef TARGET_ARM
3771
    if (((CPUARMState *)cpu_env)->eabi)
3772
      {
3773
        arg2 = arg3;
3774
        arg3 = arg4;
3775
      }
3776
#endif
3777
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3778
}
3779
#endif
3780

    
3781
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3782
                                               abi_ulong target_addr)
3783
{
3784
    struct target_timespec *target_ts;
3785

    
3786
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3787
        return -TARGET_EFAULT;
3788
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3789
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3790
    unlock_user_struct(target_ts, target_addr, 0);
3791
    return 0;
3792
}
3793

    
3794
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3795
                                               struct timespec *host_ts)
3796
{
3797
    struct target_timespec *target_ts;
3798

    
3799
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3800
        return -TARGET_EFAULT;
3801
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3802
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3803
    unlock_user_struct(target_ts, target_addr, 1);
3804
    return 0;
3805
}
3806

    
3807
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3808
static inline abi_long host_to_target_stat64(void *cpu_env,
3809
                                             abi_ulong target_addr,
3810
                                             struct stat *host_st)
3811
{
3812
#ifdef TARGET_ARM
3813
    if (((CPUARMState *)cpu_env)->eabi) {
3814
        struct target_eabi_stat64 *target_st;
3815

    
3816
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3817
            return -TARGET_EFAULT;
3818
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3819
        __put_user(host_st->st_dev, &target_st->st_dev);
3820
        __put_user(host_st->st_ino, &target_st->st_ino);
3821
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3822
        __put_user(host_st->st_ino, &target_st->__st_ino);
3823
#endif
3824
        __put_user(host_st->st_mode, &target_st->st_mode);
3825
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3826
        __put_user(host_st->st_uid, &target_st->st_uid);
3827
        __put_user(host_st->st_gid, &target_st->st_gid);
3828
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3829
        __put_user(host_st->st_size, &target_st->st_size);
3830
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3831
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3832
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3833
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3834
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3835
        unlock_user_struct(target_st, target_addr, 1);
3836
    } else
3837
#endif
3838
    {
3839
#if TARGET_LONG_BITS == 64
3840
        struct target_stat *target_st;
3841
#else
3842
        struct target_stat64 *target_st;
3843
#endif
3844

    
3845
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3846
            return -TARGET_EFAULT;
3847
        memset(target_st, 0, sizeof(*target_st));
3848
        __put_user(host_st->st_dev, &target_st->st_dev);
3849
        __put_user(host_st->st_ino, &target_st->st_ino);
3850
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3851
        __put_user(host_st->st_ino, &target_st->__st_ino);
3852
#endif
3853
        __put_user(host_st->st_mode, &target_st->st_mode);
3854
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3855
        __put_user(host_st->st_uid, &target_st->st_uid);
3856
        __put_user(host_st->st_gid, &target_st->st_gid);
3857
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3858
        /* XXX: better use of kernel struct */
3859
        __put_user(host_st->st_size, &target_st->st_size);
3860
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3861
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3862
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3863
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3864
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3865
        unlock_user_struct(target_st, target_addr, 1);
3866
    }
3867

    
3868
    return 0;
3869
}
3870
#endif
3871

    
3872
#if defined(USE_NPTL)
3873
/* ??? Using host futex calls even when target atomic operations
3874
   are not really atomic probably breaks things.  However implementing
3875
   futexes locally would make futexes shared between multiple processes
3876
   tricky.  However they're probably useless because guest atomic
3877
   operations won't work either.  */
3878
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3879
                    target_ulong uaddr2, int val3)
3880
{
3881
    struct timespec ts, *pts;
3882

    
3883
    /* ??? We assume FUTEX_* constants are the same on both host
3884
       and target.  */
3885
    switch (op) {
3886
    case FUTEX_WAIT:
3887
        if (timeout) {
3888
            pts = &ts;
3889
            target_to_host_timespec(pts, timeout);
3890
        } else {
3891
            pts = NULL;
3892
        }
3893
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3894
                         pts, NULL, 0));
3895
    case FUTEX_WAKE:
3896
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3897
    case FUTEX_FD:
3898
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3899
    case FUTEX_REQUEUE:
3900
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3901
                         NULL, g2h(uaddr2), 0));
3902
    case FUTEX_CMP_REQUEUE:
3903
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3904
                         NULL, g2h(uaddr2), tswap32(val3)));
3905
    default:
3906
        return -TARGET_ENOSYS;
3907
    }
3908
}
3909
#endif
3910

    
3911
/* Map host to target signal numbers for the wait family of syscalls.
3912
   Assume all other status bits are the same.  */
3913
static int host_to_target_waitstatus(int status)
3914
{
3915
    if (WIFSIGNALED(status)) {
3916
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
3917
    }
3918
    if (WIFSTOPPED(status)) {
3919
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
3920
               | (status & 0xff);
3921
    }
3922
    return status;
3923
}
3924

    
3925
int get_osversion(void)
3926
{
3927
    static int osversion;
3928
    struct new_utsname buf;
3929
    const char *s;
3930
    int i, n, tmp;
3931
    if (osversion)
3932
        return osversion;
3933
    if (qemu_uname_release && *qemu_uname_release) {
3934
        s = qemu_uname_release;
3935
    } else {
3936
        if (sys_uname(&buf))
3937
            return 0;
3938
        s = buf.release;
3939
    }
3940
    tmp = 0;
3941
    for (i = 0; i < 3; i++) {
3942
        n = 0;
3943
        while (*s >= '0' && *s <= '9') {
3944
            n *= 10;
3945
            n += *s - '0';
3946
            s++;
3947
        }
3948
        tmp = (tmp << 8) + n;
3949
        if (*s == '.')
3950
            s++;
3951
    }
3952
    osversion = tmp;
3953
    return osversion;
3954
}
3955

    
3956
/* do_syscall() should always have a single exit point at the end so
3957
   that actions, such as logging of syscall results, can be performed.
3958
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3959
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3960
                    abi_long arg2, abi_long arg3, abi_long arg4,
3961
                    abi_long arg5, abi_long arg6)
3962
{
3963
    abi_long ret;
3964
    struct stat st;
3965
    struct statfs stfs;
3966
    void *p;
3967

    
3968
#ifdef DEBUG
3969
    gemu_log("syscall %d", num);
3970
#endif
3971
    if(do_strace)
3972
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3973

    
3974
    switch(num) {
3975
    case TARGET_NR_exit:
3976
#ifdef USE_NPTL
3977
      /* In old applications this may be used to implement _exit(2).
3978
         However in threaded applictions it is used for thread termination,
3979
         and _exit_group is used for application termination.
3980
         Do thread termination if we have more then one thread.  */
3981
      /* FIXME: This probably breaks if a signal arrives.  We should probably
3982
         be disabling signals.  */
3983
      if (first_cpu->next_cpu) {
3984
          TaskState *ts;
3985
          CPUState **lastp;
3986
          CPUState *p;
3987

    
3988
          cpu_list_lock();
3989
          lastp = &first_cpu;
3990
          p = first_cpu;
3991
          while (p && p != (CPUState *)cpu_env) {
3992
              lastp = &p->next_cpu;
3993
              p = p->next_cpu;
3994
          }
3995
          /* If we didn't find the CPU for this thread then something is
3996
             horribly wrong.  */
3997
          if (!p)
3998
              abort();
3999
          /* Remove the CPU from the list.  */
4000
          *lastp = p->next_cpu;
4001
          cpu_list_unlock();
4002
          ts = ((CPUState *)cpu_env)->opaque;
4003
          if (ts->child_tidptr) {
4004
              put_user_u32(0, ts->child_tidptr);
4005
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4006
                        NULL, NULL, 0);
4007
          }
4008
          /* TODO: Free CPU state.  */
4009
          pthread_exit(NULL);
4010
      }
4011
#endif
4012
#ifdef HAVE_GPROF
4013
        _mcleanup();
4014
#endif
4015
        gdb_exit(cpu_env, arg1);
4016
        _exit(arg1);
4017
        ret = 0; /* avoid warning */
4018
        break;
4019
    case TARGET_NR_read:
4020
        if (arg3 == 0)
4021
            ret = 0;
4022
        else {
4023
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4024
                goto efault;
4025
            ret = get_errno(read(arg1, p, arg3));
4026
            unlock_user(p, arg2, ret);
4027
        }
4028
        break;
4029
    case TARGET_NR_write:
4030
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4031
            goto efault;
4032
        ret = get_errno(write(arg1, p, arg3));
4033
        unlock_user(p, arg2, 0);
4034
        break;
4035
    case TARGET_NR_open:
4036
        if (!(p = lock_user_string(arg1)))
4037
            goto efault;
4038
        ret = get_errno(open(path(p),
4039
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4040
                             arg3));
4041
        unlock_user(p, arg1, 0);
4042
        break;
4043
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4044
    case TARGET_NR_openat:
4045
        if (!(p = lock_user_string(arg2)))
4046
            goto efault;
4047
        ret = get_errno(sys_openat(arg1,
4048
                                   path(p),
4049
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4050
                                   arg4));
4051
        unlock_user(p, arg2, 0);
4052
        break;
4053
#endif
4054
    case TARGET_NR_close:
4055
        ret = get_errno(close(arg1));
4056
        break;
4057
    case TARGET_NR_brk:
4058
        ret = do_brk(arg1);
4059
        break;
4060
    case TARGET_NR_fork:
4061
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4062
        break;
4063
#ifdef TARGET_NR_waitpid
4064
    case TARGET_NR_waitpid:
4065
        {
4066
            int status;
4067
            ret = get_errno(waitpid(arg1, &status, arg3));
4068
            if (!is_error(ret) && arg2
4069
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4070
                goto efault;
4071
        }
4072
        break;
4073
#endif
4074
#ifdef TARGET_NR_waitid
4075
    case TARGET_NR_waitid:
4076
        {
4077
            siginfo_t info;
4078
            info.si_pid = 0;
4079
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4080
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4081
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4082
                    goto efault;
4083
                host_to_target_siginfo(p, &info);
4084
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4085
            }
4086
        }
4087
        break;
4088
#endif
4089
#ifdef TARGET_NR_creat /* not on alpha */
4090
    case TARGET_NR_creat:
4091
        if (!(p = lock_user_string(arg1)))
4092
            goto efault;
4093
        ret = get_errno(creat(p, arg2));
4094
        unlock_user(p, arg1, 0);
4095
        break;
4096
#endif
4097
    case TARGET_NR_link:
4098
        {
4099
            void * p2;
4100
            p = lock_user_string(arg1);
4101
            p2 = lock_user_string(arg2);
4102
            if (!p || !p2)
4103
                ret = -TARGET_EFAULT;
4104
            else
4105
                ret = get_errno(link(p, p2));
4106
            unlock_user(p2, arg2, 0);
4107
            unlock_user(p, arg1, 0);
4108
        }
4109
        break;
4110
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4111
    case TARGET_NR_linkat:
4112
        {
4113
            void * p2 = NULL;
4114
            if (!arg2 || !arg4)
4115
                goto efault;
4116
            p  = lock_user_string(arg2);
4117
            p2 = lock_user_string(arg4);
4118
            if (!p || !p2)
4119
                ret = -TARGET_EFAULT;
4120
            else
4121
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4122
            unlock_user(p, arg2, 0);
4123
            unlock_user(p2, arg4, 0);
4124
        }
4125
        break;
4126
#endif
4127
    case TARGET_NR_unlink:
4128
        if (!(p = lock_user_string(arg1)))
4129
            goto efault;
4130
        ret = get_errno(unlink(p));
4131
        unlock_user(p, arg1, 0);
4132
        break;
4133
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4134
    case TARGET_NR_unlinkat:
4135
        if (!(p = lock_user_string(arg2)))
4136
            goto efault;
4137
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4138
        unlock_user(p, arg2, 0);
4139
        break;
4140
#endif
4141
    case TARGET_NR_execve:
4142
        {
4143
            char **argp, **envp;
4144
            int argc, envc;
4145
            abi_ulong gp;
4146
            abi_ulong guest_argp;
4147
            abi_ulong guest_envp;
4148
            abi_ulong addr;
4149
            char **q;
4150

    
4151
            argc = 0;
4152
            guest_argp = arg2;
4153
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4154
                if (get_user_ual(addr, gp))
4155
                    goto efault;
4156
                if (!addr)
4157
                    break;
4158
                argc++;
4159
            }
4160
            envc = 0;
4161
            guest_envp = arg3;
4162
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4163
                if (get_user_ual(addr, gp))
4164
                    goto efault;
4165
                if (!addr)
4166
                    break;
4167
                envc++;
4168
            }
4169

    
4170
            argp = alloca((argc + 1) * sizeof(void *));
4171
            envp = alloca((envc + 1) * sizeof(void *));
4172

    
4173
            for (gp = guest_argp, q = argp; gp;
4174
                  gp += sizeof(abi_ulong), q++) {
4175
                if (get_user_ual(addr, gp))
4176
                    goto execve_efault;
4177
                if (!addr)
4178
                    break;
4179
                if (!(*q = lock_user_string(addr)))
4180
                    goto execve_efault;
4181
            }
4182
            *q = NULL;
4183

    
4184
            for (gp = guest_envp, q = envp; gp;
4185
                  gp += sizeof(abi_ulong), q++) {
4186
                if (get_user_ual(addr, gp))
4187
                    goto execve_efault;
4188
                if (!addr)
4189
                    break;
4190
                if (!(*q = lock_user_string(addr)))
4191
                    goto execve_efault;
4192
            }
4193
            *q = NULL;
4194

    
4195
            if (!(p = lock_user_string(arg1)))
4196
                goto execve_efault;
4197
            ret = get_errno(execve(p, argp, envp));
4198
            unlock_user(p, arg1, 0);
4199

    
4200
            goto execve_end;
4201

    
4202
        execve_efault:
4203
            ret = -TARGET_EFAULT;
4204

    
4205
        execve_end:
4206
            for (gp = guest_argp, q = argp; *q;
4207
                  gp += sizeof(abi_ulong), q++) {
4208
                if (get_user_ual(addr, gp)
4209
                    || !addr)
4210
                    break;
4211
                unlock_user(*q, addr, 0);
4212
            }
4213
            for (gp = guest_envp, q = envp; *q;
4214
                  gp += sizeof(abi_ulong), q++) {
4215
                if (get_user_ual(addr, gp)
4216
                    || !addr)
4217
                    break;
4218
                unlock_user(*q, addr, 0);
4219
            }
4220
        }
4221
        break;
4222
    case TARGET_NR_chdir:
4223
        if (!(p = lock_user_string(arg1)))
4224
            goto efault;
4225
        ret = get_errno(chdir(p));
4226
        unlock_user(p, arg1, 0);
4227
        break;
4228
#ifdef TARGET_NR_time
4229
    case TARGET_NR_time:
4230
        {
4231
            time_t host_time;
4232
            ret = get_errno(time(&host_time));
4233
            if (!is_error(ret)
4234
                && arg1
4235
                && put_user_sal(host_time, arg1))
4236
                goto efault;
4237
        }
4238
        break;
4239
#endif
4240
    case TARGET_NR_mknod:
4241
        if (!(p = lock_user_string(arg1)))
4242
            goto efault;
4243
        ret = get_errno(mknod(p, arg2, arg3));
4244
        unlock_user(p, arg1, 0);
4245
        break;
4246
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4247
    case TARGET_NR_mknodat:
4248
        if (!(p = lock_user_string(arg2)))
4249
            goto efault;
4250
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4251
        unlock_user(p, arg2, 0);
4252
        break;
4253
#endif
4254
    case TARGET_NR_chmod:
4255
        if (!(p = lock_user_string(arg1)))
4256
            goto efault;
4257
        ret = get_errno(chmod(p, arg2));
4258
        unlock_user(p, arg1, 0);
4259
        break;
4260
#ifdef TARGET_NR_break
4261
    case TARGET_NR_break:
4262
        goto unimplemented;
4263
#endif
4264
#ifdef TARGET_NR_oldstat
4265
    case TARGET_NR_oldstat:
4266
        goto unimplemented;
4267
#endif
4268
    case TARGET_NR_lseek:
4269
        ret = get_errno(lseek(arg1, arg2, arg3));
4270
        break;
4271
#ifdef TARGET_NR_getxpid
4272
    case TARGET_NR_getxpid:
4273
#else
4274
    case TARGET_NR_getpid:
4275
#endif
4276
        ret = get_errno(getpid());
4277
        break;
4278
    case TARGET_NR_mount:
4279
                {
4280
                        /* need to look at the data field */
4281
                        void *p2, *p3;
4282
                        p = lock_user_string(arg1);
4283
                        p2 = lock_user_string(arg2);
4284
                        p3 = lock_user_string(arg3);
4285
                        if (!p || !p2 || !p3)
4286
                            ret = -TARGET_EFAULT;
4287
                        else
4288
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4289
                             * do that since it's not guaranteed to be a NULL-terminated
4290
                             * string.
4291
                             */
4292
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4293
                        unlock_user(p, arg1, 0);
4294
                        unlock_user(p2, arg2, 0);
4295
                        unlock_user(p3, arg3, 0);
4296
                        break;
4297
                }
4298
#ifdef TARGET_NR_umount
4299
    case TARGET_NR_umount:
4300
        if (!(p = lock_user_string(arg1)))
4301
            goto efault;
4302
        ret = get_errno(umount(p));
4303
        unlock_user(p, arg1, 0);
4304
        break;
4305
#endif
4306
#ifdef TARGET_NR_stime /* not on alpha */
4307
    case TARGET_NR_stime:
4308
        {
4309
            time_t host_time;
4310
            if (get_user_sal(host_time, arg1))
4311
                goto efault;
4312
            ret = get_errno(stime(&host_time));
4313
        }
4314
        break;
4315
#endif
4316
    case TARGET_NR_ptrace:
4317
        goto unimplemented;
4318
#ifdef TARGET_NR_alarm /* not on alpha */
4319
    case TARGET_NR_alarm:
4320
        ret = alarm(arg1);
4321
        break;
4322
#endif
4323
#ifdef TARGET_NR_oldfstat
4324
    case TARGET_NR_oldfstat:
4325
        goto unimplemented;
4326
#endif
4327
#ifdef TARGET_NR_pause /* not on alpha */
4328
    case TARGET_NR_pause:
4329
        ret = get_errno(pause());
4330
        break;
4331
#endif
4332
#ifdef TARGET_NR_utime
4333
    case TARGET_NR_utime:
4334
        {
4335
            struct utimbuf tbuf, *host_tbuf;
4336
            struct target_utimbuf *target_tbuf;
4337
            if (arg2) {
4338
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4339
                    goto efault;
4340
                tbuf.actime = tswapl(target_tbuf->actime);
4341
                tbuf.modtime = tswapl(target_tbuf->modtime);
4342
                unlock_user_struct(target_tbuf, arg2, 0);
4343
                host_tbuf = &tbuf;
4344
            } else {
4345
                host_tbuf = NULL;
4346
            }
4347
            if (!(p = lock_user_string(arg1)))
4348
                goto efault;
4349
            ret = get_errno(utime(p, host_tbuf));
4350
            unlock_user(p, arg1, 0);
4351
        }
4352
        break;
4353
#endif
4354
    case TARGET_NR_utimes:
4355
        {
4356
            struct timeval *tvp, tv[2];
4357
            if (arg2) {
4358
                if (copy_from_user_timeval(&tv[0], arg2)
4359
                    || copy_from_user_timeval(&tv[1],
4360
                                              arg2 + sizeof(struct target_timeval)))
4361
                    goto efault;
4362
                tvp = tv;
4363
            } else {
4364
                tvp = NULL;
4365
            }
4366
            if (!(p = lock_user_string(arg1)))
4367
                goto efault;
4368
            ret = get_errno(utimes(p, tvp));
4369
            unlock_user(p, arg1, 0);
4370
        }
4371
        break;
4372
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4373
    case TARGET_NR_futimesat:
4374
        {
4375
            struct timeval *tvp, tv[2];
4376
            if (arg3) {
4377
                if (copy_from_user_timeval(&tv[0], arg3)
4378
                    || copy_from_user_timeval(&tv[1],
4379
                                              arg3 + sizeof(struct target_timeval)))
4380
                    goto efault;
4381
                tvp = tv;
4382
            } else {
4383
                tvp = NULL;
4384
            }
4385
            if (!(p = lock_user_string(arg2)))
4386
                goto efault;
4387
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4388
            unlock_user(p, arg2, 0);
4389
        }
4390
        break;
4391
#endif
4392
#ifdef TARGET_NR_stty
4393
    case TARGET_NR_stty:
4394
        goto unimplemented;
4395
#endif
4396
#ifdef TARGET_NR_gtty
4397
    case TARGET_NR_gtty:
4398
        goto unimplemented;
4399
#endif
4400
    case TARGET_NR_access:
4401
        if (!(p = lock_user_string(arg1)))
4402
            goto efault;
4403
        ret = get_errno(access(p, arg2));
4404
        unlock_user(p, arg1, 0);
4405
        break;
4406
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4407
    case TARGET_NR_faccessat:
4408
        if (!(p = lock_user_string(arg2)))
4409
            goto efault;
4410
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4411
        unlock_user(p, arg2, 0);
4412
        break;
4413
#endif
4414
#ifdef TARGET_NR_nice /* not on alpha */
4415
    case TARGET_NR_nice:
4416
        ret = get_errno(nice(arg1));
4417
        break;
4418
#endif
4419
#ifdef TARGET_NR_ftime
4420
    case TARGET_NR_ftime:
4421
        goto unimplemented;
4422
#endif
4423
    case TARGET_NR_sync:
4424
        sync();
4425
        ret = 0;
4426
        break;
4427
    case TARGET_NR_kill:
4428
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4429
        break;
4430
    case TARGET_NR_rename:
4431
        {
4432
            void *p2;
4433
            p = lock_user_string(arg1);
4434
            p2 = lock_user_string(arg2);
4435
            if (!p || !p2)
4436
                ret = -TARGET_EFAULT;
4437
            else
4438
                ret = get_errno(rename(p, p2));
4439
            unlock_user(p2, arg2, 0);
4440
            unlock_user(p, arg1, 0);
4441
        }
4442
        break;
4443
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4444
    case TARGET_NR_renameat:
4445
        {
4446
            void *p2;
4447
            p  = lock_user_string(arg2);
4448
            p2 = lock_user_string(arg4);
4449
            if (!p || !p2)
4450
                ret = -TARGET_EFAULT;
4451
            else
4452
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4453
            unlock_user(p2, arg4, 0);
4454
            unlock_user(p, arg2, 0);
4455
        }
4456
        break;
4457
#endif
4458
    case TARGET_NR_mkdir:
4459
        if (!(p = lock_user_string(arg1)))
4460
            goto efault;
4461
        ret = get_errno(mkdir(p, arg2));
4462
        unlock_user(p, arg1, 0);
4463
        break;
4464
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4465
    case TARGET_NR_mkdirat:
4466
        if (!(p = lock_user_string(arg2)))
4467
            goto efault;
4468
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4469
        unlock_user(p, arg2, 0);
4470
        break;
4471
#endif
4472
    case TARGET_NR_rmdir:
4473
        if (!(p = lock_user_string(arg1)))
4474
            goto efault;
4475
        ret = get_errno(rmdir(p));
4476
        unlock_user(p, arg1, 0);
4477
        break;
4478
    case TARGET_NR_dup:
4479
        ret = get_errno(dup(arg1));
4480
        break;
4481
    case TARGET_NR_pipe:
4482
        {
4483
            int host_pipe[2];
4484
            ret = get_errno(pipe(host_pipe));
4485
            if (!is_error(ret)) {
4486
#if defined(TARGET_MIPS)
4487
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4488
                env->active_tc.gpr[3] = host_pipe[1];
4489
                ret = host_pipe[0];
4490
#elif defined(TARGET_SH4)
4491
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4492
                ret = host_pipe[0];
4493
#else
4494
                if (put_user_s32(host_pipe[0], arg1)
4495
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4496
                    goto efault;
4497
#endif
4498
            }
4499
        }
4500
        break;
4501
    case TARGET_NR_times:
4502
        {
4503
            struct target_tms *tmsp;
4504
            struct tms tms;
4505
            ret = get_errno(times(&tms));
4506
            if (arg1) {
4507
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4508
                if (!tmsp)
4509
                    goto efault;
4510
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4511
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4512
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4513
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4514
            }
4515
            if (!is_error(ret))
4516
                ret = host_to_target_clock_t(ret);
4517
        }
4518
        break;
4519
#ifdef TARGET_NR_prof
4520
    case TARGET_NR_prof:
4521
        goto unimplemented;
4522
#endif
4523
#ifdef TARGET_NR_signal
4524
    case TARGET_NR_signal:
4525
        goto unimplemented;
4526
#endif
4527
    case TARGET_NR_acct:
4528
        if (arg1 == 0) {
4529
            ret = get_errno(acct(NULL));
4530
        } else {
4531
            if (!(p = lock_user_string(arg1)))
4532
                goto efault;
4533
            ret = get_errno(acct(path(p)));
4534
            unlock_user(p, arg1, 0);
4535
        }
4536
        break;
4537
#ifdef TARGET_NR_umount2 /* not on alpha */
4538
    case TARGET_NR_umount2:
4539
        if (!(p = lock_user_string(arg1)))
4540
            goto efault;
4541
        ret = get_errno(umount2(p, arg2));
4542
        unlock_user(p, arg1, 0);
4543
        break;
4544
#endif
4545
#ifdef TARGET_NR_lock
4546
    case TARGET_NR_lock:
4547
        goto unimplemented;
4548
#endif
4549
    case TARGET_NR_ioctl:
4550
        ret = do_ioctl(arg1, arg2, arg3);
4551
        break;
4552
    case TARGET_NR_fcntl:
4553
        ret = do_fcntl(arg1, arg2, arg3);
4554
        break;
4555
#ifdef TARGET_NR_mpx
4556
    case TARGET_NR_mpx:
4557
        goto unimplemented;
4558
#endif
4559
    case TARGET_NR_setpgid:
4560
        ret = get_errno(setpgid(arg1, arg2));
4561
        break;
4562
#ifdef TARGET_NR_ulimit
4563
    case TARGET_NR_ulimit:
4564
        goto unimplemented;
4565
#endif
4566
#ifdef TARGET_NR_oldolduname
4567
    case TARGET_NR_oldolduname:
4568
        goto unimplemented;
4569
#endif
4570
    case TARGET_NR_umask:
4571
        ret = get_errno(umask(arg1));
4572
        break;
4573
    case TARGET_NR_chroot:
4574
        if (!(p = lock_user_string(arg1)))
4575
            goto efault;
4576
        ret = get_errno(chroot(p));
4577
        unlock_user(p, arg1, 0);
4578
        break;
4579
    case TARGET_NR_ustat:
4580
        goto unimplemented;
4581
    case TARGET_NR_dup2:
4582
        ret = get_errno(dup2(arg1, arg2));
4583
        break;
4584
#ifdef TARGET_NR_getppid /* not on alpha */
4585
    case TARGET_NR_getppid:
4586
        ret = get_errno(getppid());
4587
        break;
4588
#endif
4589
    case TARGET_NR_getpgrp:
4590
        ret = get_errno(getpgrp());
4591
        break;
4592
    case TARGET_NR_setsid:
4593
        ret = get_errno(setsid());
4594
        break;
4595
#ifdef TARGET_NR_sigaction
4596
    case TARGET_NR_sigaction:
4597
        {
4598
#if !defined(TARGET_MIPS)
4599
            struct target_old_sigaction *old_act;
4600
            struct target_sigaction act, oact, *pact;
4601
            if (arg2) {
4602
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4603
                    goto efault;
4604
                act._sa_handler = old_act->_sa_handler;
4605
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4606
                act.sa_flags = old_act->sa_flags;
4607
                act.sa_restorer = old_act->sa_restorer;
4608
                unlock_user_struct(old_act, arg2, 0);
4609
                pact = &act;
4610
            } else {
4611
                pact = NULL;
4612
            }
4613
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4614
            if (!is_error(ret) && arg3) {
4615
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4616
                    goto efault;
4617
                old_act->_sa_handler = oact._sa_handler;
4618
                old_act->sa_mask = oact.sa_mask.sig[0];
4619
                old_act->sa_flags = oact.sa_flags;
4620
                old_act->sa_restorer = oact.sa_restorer;
4621
                unlock_user_struct(old_act, arg3, 1);
4622
            }
4623
#else
4624
            struct target_sigaction act, oact, *pact, *old_act;
4625

    
4626
            if (arg2) {
4627
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4628
                    goto efault;
4629
                act._sa_handler = old_act->_sa_handler;
4630
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4631
                act.sa_flags = old_act->sa_flags;
4632
                unlock_user_struct(old_act, arg2, 0);
4633
                pact = &act;
4634
            } else {
4635
                pact = NULL;
4636
            }
4637

    
4638
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4639

    
4640
            if (!is_error(ret) && arg3) {
4641
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4642
                    goto efault;
4643
                old_act->_sa_handler = oact._sa_handler;
4644
                old_act->sa_flags = oact.sa_flags;
4645
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4646
                old_act->sa_mask.sig[1] = 0;
4647
                old_act->sa_mask.sig[2] = 0;
4648
                old_act->sa_mask.sig[3] = 0;
4649
                unlock_user_struct(old_act, arg3, 1);
4650
            }
4651
#endif
4652
        }
4653
        break;
4654
#endif
4655
    case TARGET_NR_rt_sigaction:
4656
        {
4657
            struct target_sigaction *act;
4658
            struct target_sigaction *oact;
4659

    
4660
            if (arg2) {
4661
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4662
                    goto efault;
4663
            } else
4664
                act = NULL;
4665
            if (arg3) {
4666
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4667
                    ret = -TARGET_EFAULT;
4668
                    goto rt_sigaction_fail;
4669
                }
4670
            } else
4671
                oact = NULL;
4672
            ret = get_errno(do_sigaction(arg1, act, oact));
4673
        rt_sigaction_fail:
4674
            if (act)
4675
                unlock_user_struct(act, arg2, 0);
4676
            if (oact)
4677
                unlock_user_struct(oact, arg3, 1);
4678
        }
4679
        break;
4680
#ifdef TARGET_NR_sgetmask /* not on alpha */
4681
    case TARGET_NR_sgetmask:
4682
        {
4683
            sigset_t cur_set;
4684
            abi_ulong target_set;
4685
            sigprocmask(0, NULL, &cur_set);
4686
            host_to_target_old_sigset(&target_set, &cur_set);
4687
            ret = target_set;
4688
        }
4689
        break;
4690
#endif
4691
#ifdef TARGET_NR_ssetmask /* not on alpha */
4692
    case TARGET_NR_ssetmask:
4693
        {
4694
            sigset_t set, oset, cur_set;
4695
            abi_ulong target_set = arg1;
4696
            sigprocmask(0, NULL, &cur_set);
4697
            target_to_host_old_sigset(&set, &target_set);
4698
            sigorset(&set, &set, &cur_set);
4699
            sigprocmask(SIG_SETMASK, &set, &oset);
4700
            host_to_target_old_sigset(&target_set, &oset);
4701
            ret = target_set;
4702
        }
4703
        break;
4704
#endif
4705
#ifdef TARGET_NR_sigprocmask
4706
    case TARGET_NR_sigprocmask:
4707
        {
4708
            int how = arg1;
4709
            sigset_t set, oldset, *set_ptr;
4710

    
4711
            if (arg2) {
4712
                switch(how) {
4713
                case TARGET_SIG_BLOCK:
4714
                    how = SIG_BLOCK;
4715
                    break;
4716
                case TARGET_SIG_UNBLOCK:
4717
                    how = SIG_UNBLOCK;
4718
                    break;
4719
                case TARGET_SIG_SETMASK:
4720
                    how = SIG_SETMASK;
4721
                    break;
4722
                default:
4723
                    ret = -TARGET_EINVAL;
4724
                    goto fail;
4725
                }
4726
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4727
                    goto efault;
4728
                target_to_host_old_sigset(&set, p);
4729
                unlock_user(p, arg2, 0);
4730
                set_ptr = &set;
4731
            } else {
4732
                how = 0;
4733
                set_ptr = NULL;
4734
            }
4735
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4736
            if (!is_error(ret) && arg3) {
4737
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4738
                    goto efault;
4739
                host_to_target_old_sigset(p, &oldset);
4740
                unlock_user(p, arg3, sizeof(target_sigset_t));
4741
            }
4742
        }
4743
        break;
4744
#endif
4745
    case TARGET_NR_rt_sigprocmask:
4746
        {
4747
            int how = arg1;
4748
            sigset_t set, oldset, *set_ptr;
4749

    
4750
            if (arg2) {
4751
                switch(how) {
4752
                case TARGET_SIG_BLOCK:
4753
                    how = SIG_BLOCK;
4754
                    break;
4755
                case TARGET_SIG_UNBLOCK:
4756
                    how = SIG_UNBLOCK;
4757
                    break;
4758
                case TARGET_SIG_SETMASK:
4759
                    how = SIG_SETMASK;
4760
                    break;
4761
                default:
4762
                    ret = -TARGET_EINVAL;
4763
                    goto fail;
4764
                }
4765
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4766
                    goto efault;
4767
                target_to_host_sigset(&set, p);
4768
                unlock_user(p, arg2, 0);
4769
                set_ptr = &set;
4770
            } else {
4771
                how = 0;
4772
                set_ptr = NULL;
4773
            }
4774
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4775
            if (!is_error(ret) && arg3) {
4776
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4777
                    goto efault;
4778
                host_to_target_sigset(p, &oldset);
4779
                unlock_user(p, arg3, sizeof(target_sigset_t));
4780
            }
4781
        }
4782
        break;
4783
#ifdef TARGET_NR_sigpending
4784
    case TARGET_NR_sigpending:
4785
        {
4786
            sigset_t set;
4787
            ret = get_errno(sigpending(&set));
4788
            if (!is_error(ret)) {
4789
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4790
                    goto efault;
4791
                host_to_target_old_sigset(p, &set);
4792
                unlock_user(p, arg1, sizeof(target_sigset_t));
4793
            }
4794
        }
4795
        break;
4796
#endif
4797
    case TARGET_NR_rt_sigpending:
4798
        {
4799
            sigset_t set;
4800
            ret = get_errno(sigpending(&set));
4801
            if (!is_error(ret)) {
4802
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4803
                    goto efault;
4804
                host_to_target_sigset(p, &set);
4805
                unlock_user(p, arg1, sizeof(target_sigset_t));
4806
            }
4807
        }
4808
        break;
4809
#ifdef TARGET_NR_sigsuspend
4810
    case TARGET_NR_sigsuspend:
4811
        {
4812
            sigset_t set;
4813
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4814
                goto efault;
4815
            target_to_host_old_sigset(&set, p);
4816
            unlock_user(p, arg1, 0);
4817
            ret = get_errno(sigsuspend(&set));
4818
        }
4819
        break;
4820
#endif
4821
    case TARGET_NR_rt_sigsuspend:
4822
        {
4823
            sigset_t set;
4824
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4825
                goto efault;
4826
            target_to_host_sigset(&set, p);
4827
            unlock_user(p, arg1, 0);
4828
            ret = get_errno(sigsuspend(&set));
4829
        }
4830
        break;
4831
    case TARGET_NR_rt_sigtimedwait:
4832
        {
4833
            sigset_t set;
4834
            struct timespec uts, *puts;
4835
            siginfo_t uinfo;
4836

    
4837
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4838
                goto efault;
4839
            target_to_host_sigset(&set, p);
4840
            unlock_user(p, arg1, 0);
4841
            if (arg3) {
4842
                puts = &uts;
4843
                target_to_host_timespec(puts, arg3);
4844
            } else {
4845
                puts = NULL;
4846
            }
4847
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4848
            if (!is_error(ret) && arg2) {
4849
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4850
                    goto efault;
4851
                host_to_target_siginfo(p, &uinfo);
4852
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4853
            }
4854
        }
4855
        break;
4856
    case TARGET_NR_rt_sigqueueinfo:
4857
        {
4858
            siginfo_t uinfo;
4859
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4860
                goto efault;
4861
            target_to_host_siginfo(&uinfo, p);
4862
            unlock_user(p, arg1, 0);
4863
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4864
        }
4865
        break;
4866
#ifdef TARGET_NR_sigreturn
4867
    case TARGET_NR_sigreturn:
4868
        /* NOTE: ret is eax, so not transcoding must be done */
4869
        ret = do_sigreturn(cpu_env);
4870
        break;
4871
#endif
4872
    case TARGET_NR_rt_sigreturn:
4873
        /* NOTE: ret is eax, so not transcoding must be done */
4874
        ret = do_rt_sigreturn(cpu_env);
4875
        break;
4876
    case TARGET_NR_sethostname:
4877
        if (!(p = lock_user_string(arg1)))
4878
            goto efault;
4879
        ret = get_errno(sethostname(p, arg2));
4880
        unlock_user(p, arg1, 0);
4881
        break;
4882
    case TARGET_NR_setrlimit:
4883
        {
4884
            /* XXX: convert resource ? */
4885
            int resource = arg1;
4886
            struct target_rlimit *target_rlim;
4887
            struct rlimit rlim;
4888
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4889
                goto efault;
4890
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4891
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4892
            unlock_user_struct(target_rlim, arg2, 0);
4893
            ret = get_errno(setrlimit(resource, &rlim));
4894
        }
4895
        break;
4896
    case TARGET_NR_getrlimit:
4897
        {
4898
            /* XXX: convert resource ? */
4899
            int resource = arg1;
4900
            struct target_rlimit *target_rlim;
4901
            struct rlimit rlim;
4902

    
4903
            ret = get_errno(getrlimit(resource, &rlim));
4904
            if (!is_error(ret)) {
4905
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4906
                    goto efault;
4907
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4908
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4909
                unlock_user_struct(target_rlim, arg2, 1);
4910
            }
4911
        }
4912
        break;
4913
    case TARGET_NR_getrusage:
4914
        {
4915
            struct rusage rusage;
4916
            ret = get_errno(getrusage(arg1, &rusage));
4917
            if (!is_error(ret)) {
4918
                host_to_target_rusage(arg2, &rusage);
4919
            }
4920
        }
4921
        break;
4922
    case TARGET_NR_gettimeofday:
4923
        {
4924
            struct timeval tv;
4925
            ret = get_errno(gettimeofday(&tv, NULL));
4926
            if (!is_error(ret)) {
4927
                if (copy_to_user_timeval(arg1, &tv))
4928
                    goto efault;
4929
            }
4930
        }
4931
        break;
4932
    case TARGET_NR_settimeofday:
4933
        {
4934
            struct timeval tv;
4935
            if (copy_from_user_timeval(&tv, arg1))
4936
                goto efault;
4937
            ret = get_errno(settimeofday(&tv, NULL));
4938
        }
4939
        break;
4940
#ifdef TARGET_NR_select
4941
    case TARGET_NR_select:
4942
        {
4943
            struct target_sel_arg_struct *sel;
4944
            abi_ulong inp, outp, exp, tvp;
4945
            long nsel;
4946

    
4947
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4948
                goto efault;
4949
            nsel = tswapl(sel->n);
4950
            inp = tswapl(sel->inp);
4951
            outp = tswapl(sel->outp);
4952
            exp = tswapl(sel->exp);
4953
            tvp = tswapl(sel->tvp);
4954
            unlock_user_struct(sel, arg1, 0);
4955
            ret = do_select(nsel, inp, outp, exp, tvp);
4956
        }
4957
        break;
4958
#endif
4959
    case TARGET_NR_symlink:
4960
        {
4961
            void *p2;
4962
            p = lock_user_string(arg1);
4963
            p2 = lock_user_string(arg2);
4964
            if (!p || !p2)
4965
                ret = -TARGET_EFAULT;
4966
            else
4967
                ret = get_errno(symlink(p, p2));
4968
            unlock_user(p2, arg2, 0);
4969
            unlock_user(p, arg1, 0);
4970
        }
4971
        break;
4972
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4973
    case TARGET_NR_symlinkat:
4974
        {
4975
            void *p2;
4976
            p  = lock_user_string(arg1);
4977
            p2 = lock_user_string(arg3);
4978
            if (!p || !p2)
4979
                ret = -TARGET_EFAULT;
4980
            else
4981
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4982
            unlock_user(p2, arg3, 0);
4983
            unlock_user(p, arg1, 0);
4984
        }
4985
        break;
4986
#endif
4987
#ifdef TARGET_NR_oldlstat
4988
    case TARGET_NR_oldlstat:
4989
        goto unimplemented;
4990
#endif
4991
    case TARGET_NR_readlink:
4992
        {
4993
            void *p2, *temp;
4994
            p = lock_user_string(arg1);
4995
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4996
            if (!p || !p2)
4997
                ret = -TARGET_EFAULT;
4998
            else {
4999
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5000
                    char real[PATH_MAX];
5001
                    temp = realpath(exec_path,real);
5002
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5003
                    snprintf((char *)p2, arg3, "%s", real);
5004
                    }
5005
                else
5006
                    ret = get_errno(readlink(path(p), p2, arg3));
5007
            }
5008
            unlock_user(p2, arg2, ret);
5009
            unlock_user(p, arg1, 0);
5010
        }
5011
        break;
5012
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5013
    case TARGET_NR_readlinkat:
5014
        {
5015
            void *p2;
5016
            p  = lock_user_string(arg2);
5017
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5018
            if (!p || !p2)
5019
                ret = -TARGET_EFAULT;
5020
            else
5021
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5022
            unlock_user(p2, arg3, ret);
5023
            unlock_user(p, arg2, 0);
5024
        }
5025
        break;
5026
#endif
5027
#ifdef TARGET_NR_uselib
5028
    case TARGET_NR_uselib:
5029
        goto unimplemented;
5030
#endif
5031
#ifdef TARGET_NR_swapon
5032
    case TARGET_NR_swapon:
5033
        if (!(p = lock_user_string(arg1)))
5034
            goto efault;
5035
        ret = get_errno(swapon(p, arg2));
5036
        unlock_user(p, arg1, 0);
5037
        break;
5038
#endif
5039
    case TARGET_NR_reboot:
5040
        goto unimplemented;
5041
#ifdef TARGET_NR_readdir
5042
    case TARGET_NR_readdir:
5043
        goto unimplemented;
5044
#endif
5045
#ifdef TARGET_NR_mmap
5046
    case TARGET_NR_mmap:
5047
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5048
        {
5049
            abi_ulong *v;
5050
            abi_ulong v1, v2, v3, v4, v5, v6;
5051
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5052
                goto efault;
5053
            v1 = tswapl(v[0]);
5054
            v2 = tswapl(v[1]);
5055
            v3 = tswapl(v[2]);
5056
            v4 = tswapl(v[3]);
5057
            v5 = tswapl(v[4]);
5058
            v6 = tswapl(v[5]);
5059
            unlock_user(v, arg1, 0);
5060
            ret = get_errno(target_mmap(v1, v2, v3,
5061
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5062
                                        v5, v6));
5063
        }
5064
#else
5065
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5066
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5067
                                    arg5,
5068
                                    arg6));
5069
#endif
5070
        break;
5071
#endif
5072
#ifdef TARGET_NR_mmap2
5073
    case TARGET_NR_mmap2:
5074
#ifndef MMAP_SHIFT
5075
#define MMAP_SHIFT 12
5076
#endif
5077
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5078
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5079
                                    arg5,
5080
                                    arg6 << MMAP_SHIFT));
5081
        break;
5082
#endif
5083
    case TARGET_NR_munmap:
5084
        ret = get_errno(target_munmap(arg1, arg2));
5085
        break;
5086
    case TARGET_NR_mprotect:
5087
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5088
        break;
5089
#ifdef TARGET_NR_mremap
5090
    case TARGET_NR_mremap:
5091
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5092
        break;
5093
#endif
5094
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5095
#ifdef TARGET_NR_msync
5096
    case TARGET_NR_msync:
5097
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5098
        break;
5099
#endif
5100
#ifdef TARGET_NR_mlock
5101
    case TARGET_NR_mlock:
5102
        ret = get_errno(mlock(g2h(arg1), arg2));
5103
        break;
5104
#endif
5105
#ifdef TARGET_NR_munlock
5106
    case TARGET_NR_munlock:
5107
        ret = get_errno(munlock(g2h(arg1), arg2));
5108
        break;
5109
#endif
5110
#ifdef TARGET_NR_mlockall
5111
    case TARGET_NR_mlockall:
5112
        ret = get_errno(mlockall(arg1));
5113
        break;
5114
#endif
5115
#ifdef TARGET_NR_munlockall
5116
    case TARGET_NR_munlockall:
5117
        ret = get_errno(munlockall());
5118
        break;
5119
#endif
5120
    case TARGET_NR_truncate:
5121
        if (!(p = lock_user_string(arg1)))
5122
            goto efault;
5123
        ret = get_errno(truncate(p, arg2));
5124
        unlock_user(p, arg1, 0);
5125
        break;
5126
    case TARGET_NR_ftruncate:
5127
        ret = get_errno(ftruncate(arg1, arg2));
5128
        break;
5129
    case TARGET_NR_fchmod:
5130
        ret = get_errno(fchmod(arg1, arg2));
5131
        break;
5132
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5133
    case TARGET_NR_fchmodat:
5134
        if (!(p = lock_user_string(arg2)))
5135
            goto efault;
5136
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5137
        unlock_user(p, arg2, 0);
5138
        break;
5139
#endif
5140
    case TARGET_NR_getpriority:
5141
        /* libc does special remapping of the return value of
5142
         * sys_getpriority() so it's just easiest to call
5143
         * sys_getpriority() directly rather than through libc. */
5144
        ret = sys_getpriority(arg1, arg2);
5145
        break;
5146
    case TARGET_NR_setpriority:
5147
        ret = get_errno(setpriority(arg1, arg2, arg3));
5148
        break;
5149
#ifdef TARGET_NR_profil
5150
    case TARGET_NR_profil:
5151
        goto unimplemented;
5152
#endif
5153
    case TARGET_NR_statfs:
5154
        if (!(p = lock_user_string(arg1)))
5155
            goto efault;
5156
        ret = get_errno(statfs(path(p), &stfs));
5157
        unlock_user(p, arg1, 0);
5158
    convert_statfs:
5159
        if (!is_error(ret)) {
5160
            struct target_statfs *target_stfs;
5161

    
5162
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5163
                goto efault;
5164
            __put_user(stfs.f_type, &target_stfs->f_type);
5165
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5166
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5167
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5168
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5169
            __put_user(stfs.f_files, &target_stfs->f_files);
5170
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5171
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5172
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5173
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5174
            unlock_user_struct(target_stfs, arg2, 1);
5175
        }
5176
        break;
5177
    case TARGET_NR_fstatfs:
5178
        ret = get_errno(fstatfs(arg1, &stfs));
5179
        goto convert_statfs;
5180
#ifdef TARGET_NR_statfs64
5181
    case TARGET_NR_statfs64:
5182
        if (!(p = lock_user_string(arg1)))
5183
            goto efault;
5184
        ret = get_errno(statfs(path(p), &stfs));
5185
        unlock_user(p, arg1, 0);
5186
    convert_statfs64:
5187
        if (!is_error(ret)) {
5188
            struct target_statfs64 *target_stfs;
5189

    
5190
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5191
                goto efault;
5192
            __put_user(stfs.f_type, &target_stfs->f_type);
5193
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5194
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5195
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5196
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5197
            __put_user(stfs.f_files, &target_stfs->f_files);
5198
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5199
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5200
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5201
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5202
            unlock_user_struct(target_stfs, arg3, 1);
5203
        }
5204
        break;
5205
    case TARGET_NR_fstatfs64:
5206
        ret = get_errno(fstatfs(arg1, &stfs));
5207
        goto convert_statfs64;
5208
#endif
5209
#ifdef TARGET_NR_ioperm
5210
    case TARGET_NR_ioperm:
5211
        goto unimplemented;
5212
#endif
5213
#ifdef TARGET_NR_socketcall
5214
    case TARGET_NR_socketcall:
5215
        ret = do_socketcall(arg1, arg2);
5216
        break;
5217
#endif
5218
#ifdef TARGET_NR_accept
5219
    case TARGET_NR_accept:
5220
        ret = do_accept(arg1, arg2, arg3);
5221
        break;
5222
#endif
5223
#ifdef TARGET_NR_bind
5224
    case TARGET_NR_bind:
5225
        ret = do_bind(arg1, arg2, arg3);
5226
        break;
5227
#endif
5228
#ifdef TARGET_NR_connect
5229
    case TARGET_NR_connect:
5230
        ret = do_connect(arg1, arg2, arg3);
5231
        break;
5232
#endif
5233
#ifdef TARGET_NR_getpeername
5234
    case TARGET_NR_getpeername:
5235
        ret = do_getpeername(arg1, arg2, arg3);
5236
        break;
5237
#endif
5238
#ifdef TARGET_NR_getsockname
5239
    case TARGET_NR_getsockname:
5240
        ret = do_getsockname(arg1, arg2, arg3);
5241
        break;
5242
#endif
5243
#ifdef TARGET_NR_getsockopt
5244
    case TARGET_NR_getsockopt:
5245
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5246
        break;
5247
#endif
5248
#ifdef TARGET_NR_listen
5249
    case TARGET_NR_listen:
5250
        ret = get_errno(listen(arg1, arg2));
5251
        break;
5252
#endif
5253
#ifdef TARGET_NR_recv
5254
    case TARGET_NR_recv:
5255
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5256
        break;
5257
#endif
5258
#ifdef TARGET_NR_recvfrom
5259
    case TARGET_NR_recvfrom:
5260
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5261
        break;
5262
#endif
5263
#ifdef TARGET_NR_recvmsg
5264
    case TARGET_NR_recvmsg:
5265
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5266
        break;
5267
#endif
5268
#ifdef TARGET_NR_send
5269
    case TARGET_NR_send:
5270
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5271
        break;
5272
#endif
5273
#ifdef TARGET_NR_sendmsg
5274
    case TARGET_NR_sendmsg:
5275
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5276
        break;
5277
#endif
5278
#ifdef TARGET_NR_sendto
5279
    case TARGET_NR_sendto:
5280
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5281
        break;
5282
#endif
5283
#ifdef TARGET_NR_shutdown
5284
    case TARGET_NR_shutdown:
5285
        ret = get_errno(shutdown(arg1, arg2));
5286
        break;
5287
#endif
5288
#ifdef TARGET_NR_socket
5289
    case TARGET_NR_socket:
5290
        ret = do_socket(arg1, arg2, arg3);
5291
        break;
5292
#endif
5293
#ifdef TARGET_NR_socketpair
5294
    case TARGET_NR_socketpair:
5295
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5296
        break;
5297
#endif
5298
#ifdef TARGET_NR_setsockopt
5299
    case TARGET_NR_setsockopt:
5300
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5301
        break;
5302
#endif
5303

    
5304
    case TARGET_NR_syslog:
5305
        if (!(p = lock_user_string(arg2)))
5306
            goto efault;
5307
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5308
        unlock_user(p, arg2, 0);
5309
        break;
5310

    
5311
    case TARGET_NR_setitimer:
5312
        {
5313
            struct itimerval value, ovalue, *pvalue;
5314

    
5315
            if (arg2) {
5316
                pvalue = &value;
5317
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5318
                    || copy_from_user_timeval(&pvalue->it_value,
5319
                                              arg2 + sizeof(struct target_timeval)))
5320
                    goto efault;
5321
            } else {
5322
                pvalue = NULL;
5323
            }
5324
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5325
            if (!is_error(ret) && arg3) {
5326
                if (copy_to_user_timeval(arg3,
5327
                                         &ovalue.it_interval)
5328
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5329
                                            &ovalue.it_value))
5330
                    goto efault;
5331
            }
5332
        }
5333
        break;
5334
    case TARGET_NR_getitimer:
5335
        {
5336
            struct itimerval value;
5337

    
5338
            ret = get_errno(getitimer(arg1, &value));
5339
            if (!is_error(ret) && arg2) {
5340
                if (copy_to_user_timeval(arg2,
5341
                                         &value.it_interval)
5342
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5343
                                            &value.it_value))
5344
                    goto efault;
5345
            }
5346
        }
5347
        break;
5348
    case TARGET_NR_stat:
5349
        if (!(p = lock_user_string(arg1)))
5350
            goto efault;
5351
        ret = get_errno(stat(path(p), &st));
5352
        unlock_user(p, arg1, 0);
5353
        goto do_stat;
5354
    case TARGET_NR_lstat:
5355
        if (!(p = lock_user_string(arg1)))
5356
            goto efault;
5357
        ret = get_errno(lstat(path(p), &st));
5358
        unlock_user(p, arg1, 0);
5359
        goto do_stat;
5360
    case TARGET_NR_fstat:
5361
        {
5362
            ret = get_errno(fstat(arg1, &st));
5363
        do_stat:
5364
            if (!is_error(ret)) {
5365
                struct target_stat *target_st;
5366

    
5367
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5368
                    goto efault;
5369
                __put_user(st.st_dev, &target_st->st_dev);
5370
                __put_user(st.st_ino, &target_st->st_ino);
5371
                __put_user(st.st_mode, &target_st->st_mode);
5372
                __put_user(st.st_uid, &target_st->st_uid);
5373
                __put_user(st.st_gid, &target_st->st_gid);
5374
                __put_user(st.st_nlink, &target_st->st_nlink);
5375
                __put_user(st.st_rdev, &target_st->st_rdev);
5376
                __put_user(st.st_size, &target_st->st_size);
5377
                __put_user(st.st_blksize, &target_st->st_blksize);
5378
                __put_user(st.st_blocks, &target_st->st_blocks);
5379
                __put_user(st.st_atime, &target_st->target_st_atime);
5380
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5381
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5382
                unlock_user_struct(target_st, arg2, 1);
5383
            }
5384
        }
5385
        break;
5386
#ifdef TARGET_NR_olduname
5387
    case TARGET_NR_olduname:
5388
        goto unimplemented;
5389
#endif
5390
#ifdef TARGET_NR_iopl
5391
    case TARGET_NR_iopl:
5392
        goto unimplemented;
5393
#endif
5394
    case TARGET_NR_vhangup:
5395
        ret = get_errno(vhangup());
5396
        break;
5397
#ifdef TARGET_NR_idle
5398
    case TARGET_NR_idle:
5399
        goto unimplemented;
5400
#endif
5401
#ifdef TARGET_NR_syscall
5402
    case TARGET_NR_syscall:
5403
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5404
            break;
5405
#endif
5406
    case TARGET_NR_wait4:
5407
        {
5408
            int status;
5409
            abi_long status_ptr = arg2;
5410
            struct rusage rusage, *rusage_ptr;
5411
            abi_ulong target_rusage = arg4;
5412
            if (target_rusage)
5413
                rusage_ptr = &rusage;
5414
            else
5415
                rusage_ptr = NULL;
5416
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5417
            if (!is_error(ret)) {
5418
                if (status_ptr) {
5419
                    status = host_to_target_waitstatus(status);
5420
                    if (put_user_s32(status, status_ptr))
5421
                        goto efault;
5422
                }
5423
                if (target_rusage)
5424
                    host_to_target_rusage(target_rusage, &rusage);
5425
            }
5426
        }
5427
        break;
5428
#ifdef TARGET_NR_swapoff
5429
    case TARGET_NR_swapoff:
5430
        if (!(p = lock_user_string(arg1)))
5431
            goto efault;
5432
        ret = get_errno(swapoff(p));
5433
        unlock_user(p, arg1, 0);
5434
        break;
5435
#endif
5436
    case TARGET_NR_sysinfo:
5437
        {
5438
            struct target_sysinfo *target_value;
5439
            struct sysinfo value;
5440
            ret = get_errno(sysinfo(&value));
5441
            if (!is_error(ret) && arg1)
5442
            {
5443
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5444
                    goto efault;
5445
                __put_user(value.uptime, &target_value->uptime);
5446
                __put_user(value.loads[0], &target_value->loads[0]);
5447
                __put_user(value.loads[1], &target_value->loads[1]);
5448
                __put_user(value.loads[2], &target_value->loads[2]);
5449
                __put_user(value.totalram, &target_value->totalram);
5450
                __put_user(value.freeram, &target_value->freeram);
5451
                __put_user(value.sharedram, &target_value->sharedram);
5452
                __put_user(value.bufferram, &target_value->bufferram);
5453
                __put_user(value.totalswap, &target_value->totalswap);
5454
                __put_user(value.freeswap, &target_value->freeswap);
5455
                __put_user(value.procs, &target_value->procs);
5456
                __put_user(value.totalhigh, &target_value->totalhigh);
5457
                __put_user(value.freehigh, &target_value->freehigh);
5458
                __put_user(value.mem_unit, &target_value->mem_unit);
5459
                unlock_user_struct(target_value, arg1, 1);
5460
            }
5461
        }
5462
        break;
5463
#ifdef TARGET_NR_ipc
5464
    case TARGET_NR_ipc:
5465
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5466
        break;
5467
#endif
5468
#ifdef TARGET_NR_semget
5469
    case TARGET_NR_semget:
5470
        ret = get_errno(semget(arg1, arg2, arg3));
5471
        break;
5472
#endif
5473
#ifdef TARGET_NR_semop
5474
    case TARGET_NR_semop:
5475
        ret = get_errno(do_semop(arg1, arg2, arg3));
5476
        break;
5477
#endif
5478
#ifdef TARGET_NR_semctl
5479
    case TARGET_NR_semctl:
5480
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5481
        break;
5482
#endif
5483
#ifdef TARGET_NR_msgctl
5484
    case TARGET_NR_msgctl:
5485
        ret = do_msgctl(arg1, arg2, arg3);
5486
        break;
5487
#endif
5488
#ifdef TARGET_NR_msgget
5489
    case TARGET_NR_msgget:
5490
        ret = get_errno(msgget(arg1, arg2));
5491
        break;
5492
#endif
5493
#ifdef TARGET_NR_msgrcv
5494
    case TARGET_NR_msgrcv:
5495
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5496
        break;
5497
#endif
5498
#ifdef TARGET_NR_msgsnd
5499
    case TARGET_NR_msgsnd:
5500
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5501
        break;
5502
#endif
5503
#ifdef TARGET_NR_shmget
5504
    case TARGET_NR_shmget:
5505
        ret = get_errno(shmget(arg1, arg2, arg3));
5506
        break;
5507
#endif
5508
#ifdef TARGET_NR_shmctl
5509
    case TARGET_NR_shmctl:
5510
        ret = do_shmctl(arg1, arg2, arg3);
5511
        break;
5512
#endif
5513
#ifdef TARGET_NR_shmat
5514
    case TARGET_NR_shmat:
5515
        ret = do_shmat(arg1, arg2, arg3);
5516
        break;
5517
#endif
5518
#ifdef TARGET_NR_shmdt
5519
    case TARGET_NR_shmdt:
5520
        ret = do_shmdt(arg1);
5521
        break;
5522
#endif
5523
    case TARGET_NR_fsync:
5524
        ret = get_errno(fsync(arg1));
5525
        break;
5526
    case TARGET_NR_clone:
5527
#if defined(TARGET_SH4)
5528
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5529
#elif defined(TARGET_CRIS)
5530
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5531
#else
5532
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5533
#endif
5534
        break;
5535
#ifdef __NR_exit_group
5536
        /* new thread calls */
5537
    case TARGET_NR_exit_group:
5538
#ifdef HAVE_GPROF
5539
        _mcleanup();
5540
#endif
5541
        gdb_exit(cpu_env, arg1);
5542
        ret = get_errno(exit_group(arg1));
5543
        break;
5544
#endif
5545
    case TARGET_NR_setdomainname:
5546
        if (!(p = lock_user_string(arg1)))
5547
            goto efault;
5548
        ret = get_errno(setdomainname(p, arg2));
5549
        unlock_user(p, arg1, 0);
5550
        break;
5551
    case TARGET_NR_uname:
5552
        /* no need to transcode because we use the linux syscall */
5553
        {
5554
            struct new_utsname * buf;
5555

    
5556
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5557
                goto efault;
5558
            ret = get_errno(sys_uname(buf));
5559
            if (!is_error(ret)) {
5560
                /* Overrite the native machine name with whatever is being
5561
                   emulated. */
5562
                strcpy (buf->machine, UNAME_MACHINE);
5563
                /* Allow the user to override the reported release.  */
5564
                if (qemu_uname_release && *qemu_uname_release)
5565
                  strcpy (buf->release, qemu_uname_release);
5566
            }
5567
            unlock_user_struct(buf, arg1, 1);
5568
        }
5569
        break;
5570
#ifdef TARGET_I386
5571
    case TARGET_NR_modify_ldt:
5572
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5573
        break;
5574
#if !defined(TARGET_X86_64)
5575
    case TARGET_NR_vm86old:
5576
        goto unimplemented;
5577
    case TARGET_NR_vm86:
5578
        ret = do_vm86(cpu_env, arg1, arg2);
5579
        break;
5580
#endif
5581
#endif
5582
    case TARGET_NR_adjtimex:
5583
        goto unimplemented;
5584
#ifdef TARGET_NR_create_module
5585
    case TARGET_NR_create_module:
5586
#endif
5587
    case TARGET_NR_init_module:
5588
    case TARGET_NR_delete_module:
5589
#ifdef TARGET_NR_get_kernel_syms
5590
    case TARGET_NR_get_kernel_syms:
5591
#endif
5592
        goto unimplemented;
5593
    case TARGET_NR_quotactl:
5594
        goto unimplemented;
5595
    case TARGET_NR_getpgid:
5596
        ret = get_errno(getpgid(arg1));
5597
        break;
5598
    case TARGET_NR_fchdir:
5599
        ret = get_errno(fchdir(arg1));
5600
        break;
5601
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5602
    case TARGET_NR_bdflush:
5603
        goto unimplemented;
5604
#endif
5605
#ifdef TARGET_NR_sysfs
5606
    case TARGET_NR_sysfs:
5607
        goto unimplemented;
5608
#endif
5609
    case TARGET_NR_personality:
5610
        ret = get_errno(personality(arg1));
5611
        break;
5612
#ifdef TARGET_NR_afs_syscall
5613
    case TARGET_NR_afs_syscall:
5614
        goto unimplemented;
5615
#endif
5616
#ifdef TARGET_NR__llseek /* Not on alpha */
5617
    case TARGET_NR__llseek:
5618
        {
5619
#if defined (__x86_64__)
5620
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5621
            if (put_user_s64(ret, arg4))
5622
                goto efault;
5623
#else
5624
            int64_t res;
5625
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5626
            if (put_user_s64(res, arg4))
5627
                goto efault;
5628
#endif
5629
        }
5630
        break;
5631
#endif
5632
    case TARGET_NR_getdents:
5633
#if TARGET_ABI_BITS != 32
5634
        goto unimplemented;
5635
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5636
        {
5637
            struct target_dirent *target_dirp;
5638
            struct linux_dirent *dirp;
5639
            abi_long count = arg3;
5640

    
5641
            dirp = malloc(count);
5642
            if (!dirp) {
5643
                ret = -TARGET_ENOMEM;
5644
                goto fail;
5645
            }
5646

    
5647
            ret = get_errno(sys_getdents(arg1, dirp, count));
5648
            if (!is_error(ret)) {
5649
                struct linux_dirent *de;
5650
                struct target_dirent *tde;
5651
                int len = ret;
5652
                int reclen, treclen;
5653
                int count1, tnamelen;
5654

    
5655
                count1 = 0;
5656
                de = dirp;
5657
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5658
                    goto efault;
5659
                tde = target_dirp;
5660
                while (len > 0) {
5661
                    reclen = de->d_reclen;
5662
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5663
                    tde->d_reclen = tswap16(treclen);
5664
                    tde->d_ino = tswapl(de->d_ino);
5665
                    tde->d_off = tswapl(de->d_off);
5666
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5667
                    if (tnamelen > 256)
5668
                        tnamelen = 256;
5669
                    /* XXX: may not be correct */
5670
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5671
                    de = (struct linux_dirent *)((char *)de + reclen);
5672
                    len -= reclen;
5673
                    tde = (struct target_dirent *)((char *)tde + treclen);
5674
                    count1 += treclen;
5675
                }
5676
                ret = count1;
5677
                unlock_user(target_dirp, arg2, ret);
5678
            }
5679
            free(dirp);
5680
        }
5681
#else
5682
        {
5683
            struct linux_dirent *dirp;
5684
            abi_long count = arg3;
5685

    
5686
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5687
                goto efault;
5688
            ret = get_errno(sys_getdents(arg1, dirp, count));
5689
            if (!is_error(ret)) {
5690
                struct linux_dirent *de;
5691
                int len = ret;
5692
                int reclen;
5693
                de = dirp;
5694
                while (len > 0) {
5695
                    reclen = de->d_reclen;
5696
                    if (reclen > len)
5697
                        break;
5698
                    de->d_reclen = tswap16(reclen);
5699
                    tswapls(&de->d_ino);
5700
                    tswapls(&de->d_off);
5701
                    de = (struct linux_dirent *)((char *)de + reclen);
5702
                    len -= reclen;
5703
                }
5704
            }
5705
            unlock_user(dirp, arg2, ret);
5706
        }
5707
#endif
5708
        break;
5709
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5710
    case TARGET_NR_getdents64:
5711
        {
5712
            struct linux_dirent64 *dirp;
5713
            abi_long count = arg3;
5714
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5715
                goto efault;
5716
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5717
            if (!is_error(ret)) {
5718
                struct linux_dirent64 *de;
5719
                int len = ret;
5720
                int reclen;
5721
                de = dirp;
5722
                while (len > 0) {
5723
                    reclen = de->d_reclen;
5724
                    if (reclen > len)
5725
                        break;
5726
                    de->d_reclen = tswap16(reclen);
5727
                    tswap64s((uint64_t *)&de->d_ino);
5728
                    tswap64s((uint64_t *)&de->d_off);
5729
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5730
                    len -= reclen;
5731
                }
5732
            }
5733
            unlock_user(dirp, arg2, ret);
5734
        }
5735
        break;
5736
#endif /* TARGET_NR_getdents64 */
5737
#ifdef TARGET_NR__newselect
5738
    case TARGET_NR__newselect:
5739
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5740
        break;
5741
#endif
5742
#ifdef TARGET_NR_poll
5743
    case TARGET_NR_poll:
5744
        {
5745
            struct target_pollfd *target_pfd;
5746
            unsigned int nfds = arg2;
5747
            int timeout = arg3;
5748
            struct pollfd *pfd;
5749
            unsigned int i;
5750

    
5751
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5752
            if (!target_pfd)
5753
                goto efault;
5754
            pfd = alloca(sizeof(struct pollfd) * nfds);
5755
            for(i = 0; i < nfds; i++) {
5756
                pfd[i].fd = tswap32(target_pfd[i].fd);
5757
                pfd[i].events = tswap16(target_pfd[i].events);
5758
            }
5759
            ret = get_errno(poll(pfd, nfds, timeout));
5760
            if (!is_error(ret)) {
5761
                for(i = 0; i < nfds; i++) {
5762
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5763
                }
5764
                ret += nfds * (sizeof(struct target_pollfd)
5765
                               - sizeof(struct pollfd));
5766
            }
5767
            unlock_user(target_pfd, arg1, ret);
5768
        }
5769
        break;
5770
#endif
5771
    case TARGET_NR_flock:
5772
        /* NOTE: the flock constant seems to be the same for every
5773
           Linux platform */
5774
        ret = get_errno(flock(arg1, arg2));
5775
        break;
5776
    case TARGET_NR_readv:
5777
        {
5778
            int count = arg3;
5779
            struct iovec *vec;
5780

    
5781
            vec = alloca(count * sizeof(struct iovec));
5782
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5783
                goto efault;
5784
            ret = get_errno(readv(arg1, vec, count));
5785
            unlock_iovec(vec, arg2, count, 1);
5786
        }
5787
        break;
5788
    case TARGET_NR_writev:
5789
        {
5790
            int count = arg3;
5791
            struct iovec *vec;
5792

    
5793
            vec = alloca(count * sizeof(struct iovec));
5794
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5795
                goto efault;
5796
            ret = get_errno(writev(arg1, vec, count));
5797
            unlock_iovec(vec, arg2, count, 0);
5798
        }
5799
        break;
5800
    case TARGET_NR_getsid:
5801
        ret = get_errno(getsid(arg1));
5802
        break;
5803
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5804
    case TARGET_NR_fdatasync:
5805
        ret = get_errno(fdatasync(arg1));
5806
        break;
5807
#endif
5808
    case TARGET_NR__sysctl:
5809
        /* We don't implement this, but ENOTDIR is always a safe
5810
           return value. */
5811
        ret = -TARGET_ENOTDIR;
5812
        break;
5813
    case TARGET_NR_sched_setparam:
5814
        {
5815
            struct sched_param *target_schp;
5816
            struct sched_param schp;
5817

    
5818
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5819
                goto efault;
5820
            schp.sched_priority = tswap32(target_schp->sched_priority);
5821
            unlock_user_struct(target_schp, arg2, 0);
5822
            ret = get_errno(sched_setparam(arg1, &schp));
5823
        }
5824
        break;
5825
    case TARGET_NR_sched_getparam:
5826
        {
5827
            struct sched_param *target_schp;
5828
            struct sched_param schp;
5829
            ret = get_errno(sched_getparam(arg1, &schp));
5830
            if (!is_error(ret)) {
5831
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5832
                    goto efault;
5833
                target_schp->sched_priority = tswap32(schp.sched_priority);
5834
                unlock_user_struct(target_schp, arg2, 1);
5835
            }
5836
        }
5837
        break;
5838
    case TARGET_NR_sched_setscheduler:
5839
        {
5840
            struct sched_param *target_schp;
5841
            struct sched_param schp;
5842
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5843
                goto efault;
5844
            schp.sched_priority = tswap32(target_schp->sched_priority);
5845
            unlock_user_struct(target_schp, arg3, 0);
5846
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5847
        }
5848
        break;
5849
    case TARGET_NR_sched_getscheduler:
5850
        ret = get_errno(sched_getscheduler(arg1));
5851
        break;
5852
    case TARGET_NR_sched_yield:
5853
        ret = get_errno(sched_yield());
5854
        break;
5855
    case TARGET_NR_sched_get_priority_max:
5856
        ret = get_errno(sched_get_priority_max(arg1));
5857
        break;
5858
    case TARGET_NR_sched_get_priority_min:
5859
        ret = get_errno(sched_get_priority_min(arg1));
5860
        break;
5861
    case TARGET_NR_sched_rr_get_interval:
5862
        {
5863
            struct timespec ts;
5864
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5865
            if (!is_error(ret)) {
5866
                host_to_target_timespec(arg2, &ts);
5867
            }
5868
        }
5869
        break;
5870
    case TARGET_NR_nanosleep:
5871
        {
5872
            struct timespec req, rem;
5873
            target_to_host_timespec(&req, arg1);
5874
            ret = get_errno(nanosleep(&req, &rem));
5875
            if (is_error(ret) && arg2) {
5876
                host_to_target_timespec(arg2, &rem);
5877
            }
5878
        }
5879
        break;
5880
#ifdef TARGET_NR_query_module
5881
    case TARGET_NR_query_module:
5882
        goto unimplemented;
5883
#endif
5884
#ifdef TARGET_NR_nfsservctl
5885
    case TARGET_NR_nfsservctl:
5886
        goto unimplemented;
5887
#endif
5888
    case TARGET_NR_prctl:
5889
        switch (arg1)
5890
            {
5891
            case PR_GET_PDEATHSIG:
5892
                {
5893
                    int deathsig;
5894
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5895
                    if (!is_error(ret) && arg2
5896
                        && put_user_ual(deathsig, arg2))
5897
                        goto efault;
5898
                }
5899
                break;
5900
            default:
5901
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5902
                break;
5903
            }
5904
        break;
5905
#ifdef TARGET_NR_arch_prctl
5906
    case TARGET_NR_arch_prctl:
5907
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5908
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5909
        break;
5910
#else
5911
        goto unimplemented;
5912
#endif
5913
#endif
5914
#ifdef TARGET_NR_pread
5915
    case TARGET_NR_pread:
5916
#ifdef TARGET_ARM
5917
        if (((CPUARMState *)cpu_env)->eabi)
5918
            arg4 = arg5;
5919
#endif
5920
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5921
            goto efault;
5922
        ret = get_errno(pread(arg1, p, arg3, arg4));
5923
        unlock_user(p, arg2, ret);
5924
        break;
5925
    case TARGET_NR_pwrite:
5926
#ifdef TARGET_ARM
5927
        if (((CPUARMState *)cpu_env)->eabi)
5928
            arg4 = arg5;
5929
#endif
5930
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5931
            goto efault;
5932
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5933
        unlock_user(p, arg2, 0);
5934
        break;
5935
#endif
5936
#ifdef TARGET_NR_pread64
5937
    case TARGET_NR_pread64:
5938
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5939
            goto efault;
5940
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5941
        unlock_user(p, arg2, ret);
5942
        break;
5943
    case TARGET_NR_pwrite64:
5944
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5945
            goto efault;
5946
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5947
        unlock_user(p, arg2, 0);
5948
        break;
5949
#endif
5950
    case TARGET_NR_getcwd:
5951
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5952
            goto efault;
5953
        ret = get_errno(sys_getcwd1(p, arg2));
5954
        unlock_user(p, arg1, ret);
5955
        break;
5956
    case TARGET_NR_capget:
5957
        goto unimplemented;
5958
    case TARGET_NR_capset:
5959
        goto unimplemented;
5960
    case TARGET_NR_sigaltstack:
5961
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5962
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5963
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5964
        break;
5965
#else
5966
        goto unimplemented;
5967
#endif
5968
    case TARGET_NR_sendfile:
5969
        goto unimplemented;
5970
#ifdef TARGET_NR_getpmsg
5971
    case TARGET_NR_getpmsg:
5972
        goto unimplemented;
5973
#endif
5974
#ifdef TARGET_NR_putpmsg
5975
    case TARGET_NR_putpmsg:
5976
        goto unimplemented;
5977
#endif
5978
#ifdef TARGET_NR_vfork
5979
    case TARGET_NR_vfork:
5980
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5981
                        0, 0, 0, 0));
5982
        break;
5983
#endif
5984
#ifdef TARGET_NR_ugetrlimit
5985
    case TARGET_NR_ugetrlimit:
5986
    {
5987
        struct rlimit rlim;
5988
        ret = get_errno(getrlimit(arg1, &rlim));
5989
        if (!is_error(ret)) {
5990
            struct target_rlimit *target_rlim;
5991
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5992
                goto efault;
5993
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5994
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5995
            unlock_user_struct(target_rlim, arg2, 1);
5996
        }
5997
        break;
5998
    }
5999
#endif
6000
#ifdef TARGET_NR_truncate64
6001
    case TARGET_NR_truncate64:
6002
        if (!(p = lock_user_string(arg1)))
6003
            goto efault;
6004
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6005
        unlock_user(p, arg1, 0);
6006
        break;
6007
#endif
6008
#ifdef TARGET_NR_ftruncate64
6009
    case TARGET_NR_ftruncate64:
6010
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6011
        break;
6012
#endif
6013
#ifdef TARGET_NR_stat64
6014
    case TARGET_NR_stat64:
6015
        if (!(p = lock_user_string(arg1)))
6016
            goto efault;
6017
        ret = get_errno(stat(path(p), &st));
6018
        unlock_user(p, arg1, 0);
6019
        if (!is_error(ret))
6020
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6021
        break;
6022
#endif
6023
#ifdef TARGET_NR_lstat64
6024
    case TARGET_NR_lstat64:
6025
        if (!(p = lock_user_string(arg1)))
6026
            goto efault;
6027
        ret = get_errno(lstat(path(p), &st));
6028
        unlock_user(p, arg1, 0);
6029
        if (!is_error(ret))
6030
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6031
        break;
6032
#endif
6033
#ifdef TARGET_NR_fstat64
6034
    case TARGET_NR_fstat64:
6035
        ret = get_errno(fstat(arg1, &st));
6036
        if (!is_error(ret))
6037
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6038
        break;
6039
#endif
6040
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6041
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6042
#ifdef TARGET_NR_fstatat64
6043
    case TARGET_NR_fstatat64:
6044
#endif
6045
#ifdef TARGET_NR_newfstatat
6046
    case TARGET_NR_newfstatat:
6047
#endif
6048
        if (!(p = lock_user_string(arg2)))
6049
            goto efault;
6050
#ifdef __NR_fstatat64
6051
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6052
#else
6053
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6054
#endif
6055
        if (!is_error(ret))
6056
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6057
        break;
6058
#endif
6059
#ifdef USE_UID16
6060
    case TARGET_NR_lchown:
6061
        if (!(p = lock_user_string(arg1)))
6062
            goto efault;
6063
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6064
        unlock_user(p, arg1, 0);
6065
        break;
6066
    case TARGET_NR_getuid:
6067
        ret = get_errno(high2lowuid(getuid()));
6068
        break;
6069
    case TARGET_NR_getgid:
6070
        ret = get_errno(high2lowgid(getgid()));
6071
        break;
6072
    case TARGET_NR_geteuid:
6073
        ret = get_errno(high2lowuid(geteuid()));
6074
        break;
6075
    case TARGET_NR_getegid:
6076
        ret = get_errno(high2lowgid(getegid()));
6077
        break;
6078
    case TARGET_NR_setreuid:
6079
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6080
        break;
6081
    case TARGET_NR_setregid:
6082
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6083
        break;
6084
    case TARGET_NR_getgroups:
6085
        {
6086
            int gidsetsize = arg1;
6087
            uint16_t *target_grouplist;
6088
            gid_t *grouplist;
6089
            int i;
6090

    
6091
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6092
            ret = get_errno(getgroups(gidsetsize, grouplist));
6093
            if (gidsetsize == 0)
6094
                break;
6095
            if (!is_error(ret)) {
6096
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6097
                if (!target_grouplist)
6098
                    goto efault;
6099
                for(i = 0;i < ret; i++)
6100
                    target_grouplist[i] = tswap16(grouplist[i]);
6101
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6102
            }
6103
        }
6104
        break;
6105
    case TARGET_NR_setgroups:
6106
        {
6107
            int gidsetsize = arg1;
6108
            uint16_t *target_grouplist;
6109
            gid_t *grouplist;
6110
            int i;
6111

    
6112
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6113
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6114
            if (!target_grouplist) {
6115
                ret = -TARGET_EFAULT;
6116
                goto fail;
6117
            }
6118
            for(i = 0;i < gidsetsize; i++)
6119
                grouplist[i] = tswap16(target_grouplist[i]);
6120
            unlock_user(target_grouplist, arg2, 0);
6121
            ret = get_errno(setgroups(gidsetsize, grouplist));
6122
        }
6123
        break;
6124
    case TARGET_NR_fchown:
6125
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6126
        break;
6127
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6128
    case TARGET_NR_fchownat:
6129
        if (!(p = lock_user_string(arg2))) 
6130
            goto efault;
6131
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6132
        unlock_user(p, arg2, 0);
6133
        break;
6134
#endif
6135
#ifdef TARGET_NR_setresuid
6136
    case TARGET_NR_setresuid:
6137
        ret = get_errno(setresuid(low2highuid(arg1),
6138
                                  low2highuid(arg2),
6139
                                  low2highuid(arg3)));
6140
        break;
6141
#endif
6142
#ifdef TARGET_NR_getresuid
6143
    case TARGET_NR_getresuid:
6144
        {
6145
            uid_t ruid, euid, suid;
6146
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6147
            if (!is_error(ret)) {
6148
                if (put_user_u16(high2lowuid(ruid), arg1)
6149
                    || put_user_u16(high2lowuid(euid), arg2)
6150
                    || put_user_u16(high2lowuid(suid), arg3))
6151
                    goto efault;
6152
            }
6153
        }
6154
        break;
6155
#endif
6156
#ifdef TARGET_NR_getresgid
6157
    case TARGET_NR_setresgid:
6158
        ret = get_errno(setresgid(low2highgid(arg1),
6159
                                  low2highgid(arg2),
6160
                                  low2highgid(arg3)));
6161
        break;
6162
#endif
6163
#ifdef TARGET_NR_getresgid
6164
    case TARGET_NR_getresgid:
6165
        {
6166
            gid_t rgid, egid, sgid;
6167
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6168
            if (!is_error(ret)) {
6169
                if (put_user_u16(high2lowgid(rgid), arg1)
6170
                    || put_user_u16(high2lowgid(egid), arg2)
6171
                    || put_user_u16(high2lowgid(sgid), arg3))
6172
                    goto efault;
6173
            }
6174
        }
6175
        break;
6176
#endif
6177
    case TARGET_NR_chown:
6178
        if (!(p = lock_user_string(arg1)))
6179
            goto efault;
6180
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6181
        unlock_user(p, arg1, 0);
6182
        break;
6183
    case TARGET_NR_setuid:
6184
        ret = get_errno(setuid(low2highuid(arg1)));
6185
        break;
6186
    case TARGET_NR_setgid:
6187
        ret = get_errno(setgid(low2highgid(arg1)));
6188
        break;
6189
    case TARGET_NR_setfsuid:
6190
        ret = get_errno(setfsuid(arg1));
6191
        break;
6192
    case TARGET_NR_setfsgid:
6193
        ret = get_errno(setfsgid(arg1));
6194
        break;
6195
#endif /* USE_UID16 */
6196

    
6197
#ifdef TARGET_NR_lchown32
6198
    case TARGET_NR_lchown32:
6199
        if (!(p = lock_user_string(arg1)))
6200
            goto efault;
6201
        ret = get_errno(lchown(p, arg2, arg3));
6202
        unlock_user(p, arg1, 0);
6203
        break;
6204
#endif
6205
#ifdef TARGET_NR_getuid32
6206
    case TARGET_NR_getuid32:
6207
        ret = get_errno(getuid());
6208
        break;
6209
#endif
6210

    
6211
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6212
   /* Alpha specific */
6213
    case TARGET_NR_getxuid:
6214
         {
6215
            uid_t euid;
6216
            euid=geteuid();
6217
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6218
         }
6219
        ret = get_errno(getuid());
6220
        break;
6221
#endif
6222
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6223
   /* Alpha specific */
6224
    case TARGET_NR_getxgid:
6225
         {
6226
            uid_t egid;
6227
            egid=getegid();
6228
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6229
         }
6230
        ret = get_errno(getgid());
6231
        break;
6232
#endif
6233

    
6234
#ifdef TARGET_NR_getgid32
6235
    case TARGET_NR_getgid32:
6236
        ret = get_errno(getgid());
6237
        break;
6238
#endif
6239
#ifdef TARGET_NR_geteuid32
6240
    case TARGET_NR_geteuid32:
6241
        ret = get_errno(geteuid());
6242
        break;
6243
#endif
6244
#ifdef TARGET_NR_getegid32
6245
    case TARGET_NR_getegid32:
6246
        ret = get_errno(getegid());
6247
        break;
6248
#endif
6249
#ifdef TARGET_NR_setreuid32
6250
    case TARGET_NR_setreuid32:
6251
        ret = get_errno(setreuid(arg1, arg2));
6252
        break;
6253
#endif
6254
#ifdef TARGET_NR_setregid32
6255
    case TARGET_NR_setregid32:
6256
        ret = get_errno(setregid(arg1, arg2));
6257
        break;
6258
#endif
6259
#ifdef TARGET_NR_getgroups32
6260
    case TARGET_NR_getgroups32:
6261
        {
6262
            int gidsetsize = arg1;
6263
            uint32_t *target_grouplist;
6264
            gid_t *grouplist;
6265
            int i;
6266

    
6267
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6268
            ret = get_errno(getgroups(gidsetsize, grouplist));
6269
            if (gidsetsize == 0)
6270
                break;
6271
            if (!is_error(ret)) {
6272
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6273
                if (!target_grouplist) {
6274
                    ret = -TARGET_EFAULT;
6275
                    goto fail;
6276
                }
6277
                for(i = 0;i < ret; i++)
6278
                    target_grouplist[i] = tswap32(grouplist[i]);
6279
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6280
            }
6281
        }
6282
        break;
6283
#endif
6284
#ifdef TARGET_NR_setgroups32
6285
    case TARGET_NR_setgroups32:
6286
        {
6287
            int gidsetsize = arg1;
6288
            uint32_t *target_grouplist;
6289
            gid_t *grouplist;
6290
            int i;
6291

    
6292
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6293
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6294
            if (!target_grouplist) {
6295
                ret = -TARGET_EFAULT;
6296
                goto fail;
6297
            }
6298
            for(i = 0;i < gidsetsize; i++)
6299
                grouplist[i] = tswap32(target_grouplist[i]);
6300
            unlock_user(target_grouplist, arg2, 0);
6301
            ret = get_errno(setgroups(gidsetsize, grouplist));
6302
        }
6303
        break;
6304
#endif
6305
#ifdef TARGET_NR_fchown32
6306
    case TARGET_NR_fchown32:
6307
        ret = get_errno(fchown(arg1, arg2, arg3));
6308
        break;
6309
#endif
6310
#ifdef TARGET_NR_setresuid32
6311
    case TARGET_NR_setresuid32:
6312
        ret = get_errno(setresuid(arg1, arg2, arg3));
6313
        break;
6314
#endif
6315
#ifdef TARGET_NR_getresuid32
6316
    case TARGET_NR_getresuid32:
6317
        {
6318
            uid_t ruid, euid, suid;
6319
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6320
            if (!is_error(ret)) {
6321
                if (put_user_u32(ruid, arg1)
6322
                    || put_user_u32(euid, arg2)
6323
                    || put_user_u32(suid, arg3))
6324
                    goto efault;
6325
            }
6326
        }
6327
        break;
6328
#endif
6329
#ifdef TARGET_NR_setresgid32
6330
    case TARGET_NR_setresgid32:
6331
        ret = get_errno(setresgid(arg1, arg2, arg3));
6332
        break;
6333
#endif
6334
#ifdef TARGET_NR_getresgid32
6335
    case TARGET_NR_getresgid32:
6336
        {
6337
            gid_t rgid, egid, sgid;
6338
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6339
            if (!is_error(ret)) {
6340
                if (put_user_u32(rgid, arg1)
6341
                    || put_user_u32(egid, arg2)
6342
                    || put_user_u32(sgid, arg3))
6343
                    goto efault;
6344
            }
6345
        }
6346
        break;
6347
#endif
6348
#ifdef TARGET_NR_chown32
6349
    case TARGET_NR_chown32:
6350
        if (!(p = lock_user_string(arg1)))
6351
            goto efault;
6352
        ret = get_errno(chown(p, arg2, arg3));
6353
        unlock_user(p, arg1, 0);
6354
        break;
6355
#endif
6356
#ifdef TARGET_NR_setuid32
6357
    case TARGET_NR_setuid32:
6358
        ret = get_errno(setuid(arg1));
6359
        break;
6360
#endif
6361
#ifdef TARGET_NR_setgid32
6362
    case TARGET_NR_setgid32:
6363
        ret = get_errno(setgid(arg1));
6364
        break;
6365
#endif
6366
#ifdef TARGET_NR_setfsuid32
6367
    case TARGET_NR_setfsuid32:
6368
        ret = get_errno(setfsuid(arg1));
6369
        break;
6370
#endif
6371
#ifdef TARGET_NR_setfsgid32
6372
    case TARGET_NR_setfsgid32:
6373
        ret = get_errno(setfsgid(arg1));
6374
        break;
6375
#endif
6376

    
6377
    case TARGET_NR_pivot_root:
6378
        goto unimplemented;
6379
#ifdef TARGET_NR_mincore
6380
    case TARGET_NR_mincore:
6381
        {
6382
            void *a;
6383
            ret = -TARGET_EFAULT;
6384
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6385
                goto efault;
6386
            if (!(p = lock_user_string(arg3)))
6387
                goto mincore_fail;
6388
            ret = get_errno(mincore(a, arg2, p));
6389
            unlock_user(p, arg3, ret);
6390
            mincore_fail:
6391
            unlock_user(a, arg1, 0);
6392
        }
6393
        break;
6394
#endif
6395
#ifdef TARGET_NR_arm_fadvise64_64
6396
    case TARGET_NR_arm_fadvise64_64:
6397
        {
6398
                /*
6399
                 * arm_fadvise64_64 looks like fadvise64_64 but
6400
                 * with different argument order
6401
                 */
6402
                abi_long temp;
6403
                temp = arg3;
6404
                arg3 = arg4;
6405
                arg4 = temp;
6406
        }
6407
#endif
6408
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6409
#ifdef TARGET_NR_fadvise64_64
6410
    case TARGET_NR_fadvise64_64:
6411
#endif
6412
        /* This is a hint, so ignoring and returning success is ok.  */
6413
        ret = get_errno(0);
6414
        break;
6415
#endif
6416
#ifdef TARGET_NR_madvise
6417
    case TARGET_NR_madvise:
6418
        /* A straight passthrough may not be safe because qemu sometimes
6419
           turns private flie-backed mappings into anonymous mappings.
6420
           This will break MADV_DONTNEED.
6421
           This is a hint, so ignoring and returning success is ok.  */
6422
        ret = get_errno(0);
6423
        break;
6424
#endif
6425
#if TARGET_ABI_BITS == 32
6426
    case TARGET_NR_fcntl64:
6427
    {
6428
        int cmd;
6429
        struct flock64 fl;
6430
        struct target_flock64 *target_fl;
6431
#ifdef TARGET_ARM
6432
        struct target_eabi_flock64 *target_efl;
6433
#endif
6434

    
6435
        switch(arg2){
6436
        case TARGET_F_GETLK64:
6437
            cmd = F_GETLK64;
6438
            break;
6439
        case TARGET_F_SETLK64:
6440
            cmd = F_SETLK64;
6441
            break;
6442
        case TARGET_F_SETLKW64:
6443
            cmd = F_SETLK64;
6444
            break;
6445
        default:
6446
            cmd = arg2;
6447
            break;
6448
        }
6449

    
6450
        switch(arg2) {
6451
        case TARGET_F_GETLK64:
6452
#ifdef TARGET_ARM
6453
            if (((CPUARMState *)cpu_env)->eabi) {
6454
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6455
                    goto efault;
6456
                fl.l_type = tswap16(target_efl->l_type);
6457
                fl.l_whence = tswap16(target_efl->l_whence);
6458
                fl.l_start = tswap64(target_efl->l_start);
6459
                fl.l_len = tswap64(target_efl->l_len);
6460
                fl.l_pid = tswapl(target_efl->l_pid);
6461
                unlock_user_struct(target_efl, arg3, 0);
6462
            } else
6463
#endif
6464
            {
6465
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6466
                    goto efault;
6467
                fl.l_type = tswap16(target_fl->l_type);
6468
                fl.l_whence = tswap16(target_fl->l_whence);
6469
                fl.l_start = tswap64(target_fl->l_start);
6470
                fl.l_len = tswap64(target_fl->l_len);
6471
                fl.l_pid = tswapl(target_fl->l_pid);
6472
                unlock_user_struct(target_fl, arg3, 0);
6473
            }
6474
            ret = get_errno(fcntl(arg1, cmd, &fl));
6475
            if (ret == 0) {
6476
#ifdef TARGET_ARM
6477
                if (((CPUARMState *)cpu_env)->eabi) {
6478
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6479
                        goto efault;
6480
                    target_efl->l_type = tswap16(fl.l_type);
6481
                    target_efl->l_whence = tswap16(fl.l_whence);
6482
                    target_efl->l_start = tswap64(fl.l_start);
6483
                    target_efl->l_len = tswap64(fl.l_len);
6484
                    target_efl->l_pid = tswapl(fl.l_pid);
6485
                    unlock_user_struct(target_efl, arg3, 1);
6486
                } else
6487
#endif
6488
                {
6489
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6490
                        goto efault;
6491
                    target_fl->l_type = tswap16(fl.l_type);
6492
                    target_fl->l_whence = tswap16(fl.l_whence);
6493
                    target_fl->l_start = tswap64(fl.l_start);
6494
                    target_fl->l_len = tswap64(fl.l_len);
6495
                    target_fl->l_pid = tswapl(fl.l_pid);
6496
                    unlock_user_struct(target_fl, arg3, 1);
6497
                }
6498
            }
6499
            break;
6500

    
6501
        case TARGET_F_SETLK64:
6502
        case TARGET_F_SETLKW64:
6503
#ifdef TARGET_ARM
6504
            if (((CPUARMState *)cpu_env)->eabi) {
6505
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6506
                    goto efault;
6507
                fl.l_type = tswap16(target_efl->l_type);
6508
                fl.l_whence = tswap16(target_efl->l_whence);
6509
                fl.l_start = tswap64(target_efl->l_start);
6510
                fl.l_len = tswap64(target_efl->l_len);
6511
                fl.l_pid = tswapl(target_efl->l_pid);
6512
                unlock_user_struct(target_efl, arg3, 0);
6513
            } else
6514
#endif
6515
            {
6516
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6517
                    goto efault;
6518
                fl.l_type = tswap16(target_fl->l_type);
6519
                fl.l_whence = tswap16(target_fl->l_whence);
6520
                fl.l_start = tswap64(target_fl->l_start);
6521
                fl.l_len = tswap64(target_fl->l_len);
6522
                fl.l_pid = tswapl(target_fl->l_pid);
6523
                unlock_user_struct(target_fl, arg3, 0);
6524
            }
6525
            ret = get_errno(fcntl(arg1, cmd, &fl));
6526
            break;
6527
        default:
6528
            ret = do_fcntl(arg1, cmd, arg3);
6529
            break;
6530
        }
6531
        break;
6532
    }
6533
#endif
6534
#ifdef TARGET_NR_cacheflush
6535
    case TARGET_NR_cacheflush:
6536
        /* self-modifying code is handled automatically, so nothing needed */
6537
        ret = 0;
6538
        break;
6539
#endif
6540
#ifdef TARGET_NR_security
6541
    case TARGET_NR_security:
6542
        goto unimplemented;
6543
#endif
6544
#ifdef TARGET_NR_getpagesize
6545
    case TARGET_NR_getpagesize:
6546
        ret = TARGET_PAGE_SIZE;
6547
        break;
6548
#endif
6549
    case TARGET_NR_gettid:
6550
        ret = get_errno(gettid());
6551
        break;
6552
#ifdef TARGET_NR_readahead
6553
    case TARGET_NR_readahead:
6554
#if TARGET_ABI_BITS == 32
6555
#ifdef TARGET_ARM
6556
        if (((CPUARMState *)cpu_env)->eabi)
6557
        {
6558
            arg2 = arg3;
6559
            arg3 = arg4;
6560
            arg4 = arg5;
6561
        }
6562
#endif
6563
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6564
#else
6565
        ret = get_errno(readahead(arg1, arg2, arg3));
6566
#endif
6567
        break;
6568
#endif
6569
#ifdef TARGET_NR_setxattr
6570
    case TARGET_NR_setxattr:
6571
    case TARGET_NR_lsetxattr:
6572
    case TARGET_NR_fsetxattr:
6573
    case TARGET_NR_getxattr:
6574
    case TARGET_NR_lgetxattr:
6575
    case TARGET_NR_fgetxattr:
6576
    case TARGET_NR_listxattr:
6577
    case TARGET_NR_llistxattr:
6578
    case TARGET_NR_flistxattr:
6579
    case TARGET_NR_removexattr:
6580
    case TARGET_NR_lremovexattr:
6581
    case TARGET_NR_fremovexattr:
6582
        ret = -TARGET_EOPNOTSUPP;
6583
        break;
6584
#endif
6585
#ifdef TARGET_NR_set_thread_area
6586
    case TARGET_NR_set_thread_area:
6587
#if defined(TARGET_MIPS)
6588
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6589
      ret = 0;
6590
      break;
6591
#elif defined(TARGET_CRIS)
6592
      if (arg1 & 0xff)
6593
          ret = -TARGET_EINVAL;
6594
      else {
6595
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6596
          ret = 0;
6597
      }
6598
      break;
6599
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6600
      ret = do_set_thread_area(cpu_env, arg1);
6601
      break;
6602
#else
6603
      goto unimplemented_nowarn;
6604
#endif
6605
#endif
6606
#ifdef TARGET_NR_get_thread_area
6607
    case TARGET_NR_get_thread_area:
6608
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6609
        ret = do_get_thread_area(cpu_env, arg1);
6610
#else
6611
        goto unimplemented_nowarn;
6612
#endif
6613
#endif
6614
#ifdef TARGET_NR_getdomainname
6615
    case TARGET_NR_getdomainname:
6616
        goto unimplemented_nowarn;
6617
#endif
6618

    
6619
#ifdef TARGET_NR_clock_gettime
6620
    case TARGET_NR_clock_gettime:
6621
    {
6622
        struct timespec ts;
6623
        ret = get_errno(clock_gettime(arg1, &ts));
6624
        if (!is_error(ret)) {
6625
            host_to_target_timespec(arg2, &ts);
6626
        }
6627
        break;
6628
    }
6629
#endif
6630
#ifdef TARGET_NR_clock_getres
6631
    case TARGET_NR_clock_getres:
6632
    {
6633
        struct timespec ts;
6634
        ret = get_errno(clock_getres(arg1, &ts));
6635
        if (!is_error(ret)) {
6636
            host_to_target_timespec(arg2, &ts);
6637
        }
6638
        break;
6639
    }
6640
#endif
6641
#ifdef TARGET_NR_clock_nanosleep
6642
    case TARGET_NR_clock_nanosleep:
6643
    {
6644
        struct timespec ts;
6645
        target_to_host_timespec(&ts, arg3);
6646
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6647
        if (arg4)
6648
            host_to_target_timespec(arg4, &ts);
6649
        break;
6650
    }
6651
#endif
6652

    
6653
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6654
    case TARGET_NR_set_tid_address:
6655
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6656
        break;
6657
#endif
6658

    
6659
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6660
    case TARGET_NR_tkill:
6661
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6662
        break;
6663
#endif
6664

    
6665
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6666
    case TARGET_NR_tgkill:
6667
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6668
                        target_to_host_signal(arg3)));
6669
        break;
6670
#endif
6671

    
6672
#ifdef TARGET_NR_set_robust_list
6673
    case TARGET_NR_set_robust_list:
6674
        goto unimplemented_nowarn;
6675
#endif
6676

    
6677
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6678
    case TARGET_NR_utimensat:
6679
        {
6680
            struct timespec *tsp, ts[2];
6681
            if (!arg3) {
6682
                tsp = NULL;
6683
            } else {
6684
                target_to_host_timespec(ts, arg3);
6685
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6686
                tsp = ts;
6687
            }
6688
            if (!arg2)
6689
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6690
            else {
6691
                if (!(p = lock_user_string(arg2))) {
6692
                    ret = -TARGET_EFAULT;
6693
                    goto fail;
6694
                }
6695
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6696
                unlock_user(p, arg2, 0);
6697
            }
6698
        }
6699
        break;
6700
#endif
6701
#if defined(USE_NPTL)
6702
    case TARGET_NR_futex:
6703
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6704
        break;
6705
#endif
6706
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6707
    case TARGET_NR_inotify_init:
6708
        ret = get_errno(sys_inotify_init());
6709
        break;
6710
#endif
6711
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6712
    case TARGET_NR_inotify_add_watch:
6713
        p = lock_user_string(arg2);
6714
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6715
        unlock_user(p, arg2, 0);
6716
        break;
6717
#endif
6718
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6719
    case TARGET_NR_inotify_rm_watch:
6720
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6721
        break;
6722
#endif
6723

    
6724
#ifdef TARGET_NR_mq_open
6725
    case TARGET_NR_mq_open:
6726
        {
6727
            struct mq_attr posix_mq_attr;
6728

    
6729
            p = lock_user_string(arg1 - 1);
6730
            if (arg4 != 0)
6731
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6732
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6733
            unlock_user (p, arg1, 0);
6734
        }
6735
        break;
6736

    
6737
    case TARGET_NR_mq_unlink:
6738
        p = lock_user_string(arg1 - 1);
6739
        ret = get_errno(mq_unlink(p));
6740
        unlock_user (p, arg1, 0);
6741
        break;
6742

    
6743
    case TARGET_NR_mq_timedsend:
6744
        {
6745
            struct timespec ts;
6746

    
6747
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6748
            if (arg5 != 0) {
6749
                target_to_host_timespec(&ts, arg5);
6750
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6751
                host_to_target_timespec(arg5, &ts);
6752
            }
6753
            else
6754
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6755
            unlock_user (p, arg2, arg3);
6756
        }
6757
        break;
6758

    
6759
    case TARGET_NR_mq_timedreceive:
6760
        {
6761
            struct timespec ts;
6762
            unsigned int prio;
6763

    
6764
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6765
            if (arg5 != 0) {
6766
                target_to_host_timespec(&ts, arg5);
6767
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6768
                host_to_target_timespec(arg5, &ts);
6769
            }
6770
            else
6771
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6772
            unlock_user (p, arg2, arg3);
6773
            if (arg4 != 0)
6774
                put_user_u32(prio, arg4);
6775
        }
6776
        break;
6777

    
6778
    /* Not implemented for now... */
6779
/*     case TARGET_NR_mq_notify: */
6780
/*         break; */
6781

    
6782
    case TARGET_NR_mq_getsetattr:
6783
        {
6784
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6785
            ret = 0;
6786
            if (arg3 != 0) {
6787
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6788
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6789
            }
6790
            if (arg2 != 0) {
6791
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6792
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6793
            }
6794

    
6795
        }
6796
        break;
6797
#endif
6798

    
6799
    default:
6800
    unimplemented:
6801
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6802
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6803
    unimplemented_nowarn:
6804
#endif
6805
        ret = -TARGET_ENOSYS;
6806
        break;
6807
    }
6808
fail:
6809
#ifdef DEBUG
6810
    gemu_log(" = %ld\n", ret);
6811
#endif
6812
    if(do_strace)
6813
        print_syscall_ret(num, ret);
6814
    return ret;
6815
efault:
6816
    ret = -TARGET_EFAULT;
6817
    goto fail;
6818
}