Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ a1606b0b

History | View | Annotate | Download (222.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, see <http://www.gnu.org/licenses/>.
18
 */
19
#define _ATFILE_SOURCE
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#include <elf.h>
25
#include <endian.h>
26
#include <errno.h>
27
#include <unistd.h>
28
#include <fcntl.h>
29
#include <time.h>
30
#include <limits.h>
31
#include <sys/types.h>
32
#include <sys/ipc.h>
33
#include <sys/msg.h>
34
#include <sys/wait.h>
35
#include <sys/time.h>
36
#include <sys/stat.h>
37
#include <sys/mount.h>
38
#include <sys/prctl.h>
39
#include <sys/resource.h>
40
#include <sys/mman.h>
41
#include <sys/swap.h>
42
#include <signal.h>
43
#include <sched.h>
44
#ifdef __ia64__
45
int __clone2(int (*fn)(void *), void *child_stack_base,
46
             size_t stack_size, int flags, void *arg, ...);
47
#endif
48
#include <sys/socket.h>
49
#include <sys/un.h>
50
#include <sys/uio.h>
51
#include <sys/poll.h>
52
#include <sys/times.h>
53
#include <sys/shm.h>
54
#include <sys/sem.h>
55
#include <sys/statfs.h>
56
#include <utime.h>
57
#include <sys/sysinfo.h>
58
#include <sys/utsname.h>
59
//#include <sys/user.h>
60
#include <netinet/ip.h>
61
#include <netinet/tcp.h>
62
#include <qemu-common.h>
63
#ifdef TARGET_GPROF
64
#include <sys/gmon.h>
65
#endif
66
#ifdef CONFIG_EVENTFD
67
#include <sys/eventfd.h>
68
#endif
69

    
70
#define termios host_termios
71
#define winsize host_winsize
72
#define termio host_termio
73
#define sgttyb host_sgttyb /* same as target */
74
#define tchars host_tchars /* same as target */
75
#define ltchars host_ltchars /* same as target */
76

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

    
91
#include "qemu.h"
92
#include "qemu-common.h"
93

    
94
#if defined(CONFIG_USE_NPTL)
95
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
96
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
97
#else
98
/* XXX: Hardcode the above values.  */
99
#define CLONE_NPTL_FLAGS2 0
100
#endif
101

    
102
//#define DEBUG
103

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

    
108

    
109
#undef _syscall0
110
#undef _syscall1
111
#undef _syscall2
112
#undef _syscall3
113
#undef _syscall4
114
#undef _syscall5
115
#undef _syscall6
116

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

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

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

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

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

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

    
154

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

    
163

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

    
193
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
194
#define __NR__llseek __NR_lseek
195
#endif
196

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

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

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

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

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

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

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

    
287
#undef COPY_UTSNAME_FIELD
288
}
289

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

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

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

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

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

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

    
474
#endif /* CONFIG_ATFILE */
475

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

    
492
#ifdef CONFIG_INOTIFY
493
#include <sys/inotify.h>
494

    
495
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
496
static int sys_inotify_init(void)
497
{
498
  return (inotify_init());
499
}
500
#endif
501
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
502
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
503
{
504
  return (inotify_add_watch(fd, pathname, mask));
505
}
506
#endif
507
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
508
static int sys_inotify_rm_watch(int fd, int32_t wd)
509
{
510
  return (inotify_rm_watch(fd, wd));
511
}
512
#endif
513
#ifdef CONFIG_INOTIFY1
514
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
515
static int sys_inotify_init1(int flags)
516
{
517
  return (inotify_init1(flags));
518
}
519
#endif
520
#endif
521
#else
522
/* Userspace can usually survive runtime without inotify */
523
#undef TARGET_NR_inotify_init
524
#undef TARGET_NR_inotify_init1
525
#undef TARGET_NR_inotify_add_watch
526
#undef TARGET_NR_inotify_rm_watch
527
#endif /* CONFIG_INOTIFY  */
528

    
529

    
530
extern int personality(int);
531
extern int flock(int, int);
532
extern int setfsuid(int);
533
extern int setfsgid(int);
534
extern int setgroups(int, gid_t *);
535

    
536
#define ERRNO_TABLE_SIZE 1200
537

    
538
/* target_to_host_errno_table[] is initialized from
539
 * host_to_target_errno_table[] in syscall_init(). */
540
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
541
};
542

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

    
655
static inline int host_to_target_errno(int err)
656
{
657
    if(host_to_target_errno_table[err])
658
        return host_to_target_errno_table[err];
659
    return err;
660
}
661

    
662
static inline int target_to_host_errno(int err)
663
{
664
    if (target_to_host_errno_table[err])
665
        return target_to_host_errno_table[err];
666
    return err;
667
}
668

    
669
static inline abi_long get_errno(abi_long ret)
670
{
671
    if (ret == -1)
672
        return -host_to_target_errno(errno);
673
    else
674
        return ret;
675
}
676

    
677
static inline int is_error(abi_long ret)
678
{
679
    return (abi_ulong)ret >= (abi_ulong)(-4096);
680
}
681

    
682
char *target_strerror(int err)
683
{
684
    return strerror(target_to_host_errno(err));
685
}
686

    
687
static abi_ulong target_brk;
688
static abi_ulong target_original_brk;
689

    
690
void target_set_brk(abi_ulong new_brk)
691
{
692
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
693
}
694

    
695
/* do_brk() must return target values and target errnos. */
696
abi_long do_brk(abi_ulong new_brk)
697
{
698
    abi_ulong brk_page;
699
    abi_long mapped_addr;
700
    int        new_alloc_size;
701

    
702
    if (!new_brk)
703
        return target_brk;
704
    if (new_brk < target_original_brk)
705
        return target_brk;
706

    
707
    brk_page = HOST_PAGE_ALIGN(target_brk);
708

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

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

    
721
    if (!is_error(mapped_addr))
722
        target_brk = new_brk;
723
    
724
    return target_brk;
725
}
726

    
727
static inline abi_long copy_from_user_fdset(fd_set *fds,
728
                                            abi_ulong target_fds_addr,
729
                                            int n)
730
{
731
    int i, nw, j, k;
732
    abi_ulong b, *target_fds;
733

    
734
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
735
    if (!(target_fds = lock_user(VERIFY_READ,
736
                                 target_fds_addr,
737
                                 sizeof(abi_ulong) * nw,
738
                                 1)))
739
        return -TARGET_EFAULT;
740

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

    
754
    unlock_user(target_fds, target_fds_addr, 0);
755

    
756
    return 0;
757
}
758

    
759
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
760
                                          const fd_set *fds,
761
                                          int n)
762
{
763
    int i, nw, j, k;
764
    abi_long v;
765
    abi_ulong *target_fds;
766

    
767
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
768
    if (!(target_fds = lock_user(VERIFY_WRITE,
769
                                 target_fds_addr,
770
                                 sizeof(abi_ulong) * nw,
771
                                 0)))
772
        return -TARGET_EFAULT;
773

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

    
784
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
785

    
786
    return 0;
787
}
788

    
789
#if defined(__alpha__)
790
#define HOST_HZ 1024
791
#else
792
#define HOST_HZ 100
793
#endif
794

    
795
static inline abi_long host_to_target_clock_t(long ticks)
796
{
797
#if HOST_HZ == TARGET_HZ
798
    return ticks;
799
#else
800
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
801
#endif
802
}
803

    
804
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
805
                                             const struct rusage *rusage)
806
{
807
    struct target_rusage *target_rusage;
808

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

    
831
    return 0;
832
}
833

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

    
839
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
840
        return -TARGET_EFAULT;
841

    
842
    __get_user(tv->tv_sec, &target_tv->tv_sec);
843
    __get_user(tv->tv_usec, &target_tv->tv_usec);
844

    
845
    unlock_user_struct(target_tv, target_tv_addr, 0);
846

    
847
    return 0;
848
}
849

    
850
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
851
                                            const struct timeval *tv)
852
{
853
    struct target_timeval *target_tv;
854

    
855
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
856
        return -TARGET_EFAULT;
857

    
858
    __put_user(tv->tv_sec, &target_tv->tv_sec);
859
    __put_user(tv->tv_usec, &target_tv->tv_usec);
860

    
861
    unlock_user_struct(target_tv, target_tv_addr, 1);
862

    
863
    return 0;
864
}
865

    
866
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
867
#include <mqueue.h>
868

    
869
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
870
                                              abi_ulong target_mq_attr_addr)
871
{
872
    struct target_mq_attr *target_mq_attr;
873

    
874
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
875
                          target_mq_attr_addr, 1))
876
        return -TARGET_EFAULT;
877

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

    
883
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
884

    
885
    return 0;
886
}
887

    
888
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
889
                                            const struct mq_attr *attr)
890
{
891
    struct target_mq_attr *target_mq_attr;
892

    
893
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
894
                          target_mq_attr_addr, 0))
895
        return -TARGET_EFAULT;
896

    
897
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
898
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
899
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
900
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
901

    
902
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
903

    
904
    return 0;
905
}
906
#endif
907

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

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

    
940
    if (target_tv_addr) {
941
        if (copy_from_user_timeval(&tv, target_tv_addr))
942
            return -TARGET_EFAULT;
943
        tv_ptr = &tv;
944
    } else {
945
        tv_ptr = NULL;
946
    }
947

    
948
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
949

    
950
    if (!is_error(ret)) {
951
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
952
            return -TARGET_EFAULT;
953
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
954
            return -TARGET_EFAULT;
955
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
956
            return -TARGET_EFAULT;
957

    
958
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
959
            return -TARGET_EFAULT;
960
    }
961

    
962
    return ret;
963
}
964

    
965
static abi_long do_pipe2(int host_pipe[], int flags)
966
{
967
#ifdef CONFIG_PIPE2
968
    return pipe2(host_pipe, flags);
969
#else
970
    return -ENOSYS;
971
#endif
972
}
973

    
974
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
975
{
976
    int host_pipe[2];
977
    abi_long ret;
978
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
979

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

    
999
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1000
                                              abi_ulong target_addr,
1001
                                              socklen_t len)
1002
{
1003
    struct target_ip_mreqn *target_smreqn;
1004

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

    
1014
    return 0;
1015
}
1016

    
1017
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1018
                                               abi_ulong target_addr,
1019
                                               socklen_t len)
1020
{
1021
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1022
    sa_family_t sa_family;
1023
    struct target_sockaddr *target_saddr;
1024

    
1025
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1026
    if (!target_saddr)
1027
        return -TARGET_EFAULT;
1028

    
1029
    sa_family = tswap16(target_saddr->sa_family);
1030

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

    
1039
    if (sa_family == AF_UNIX) {
1040
        if (len < unix_maxlen && len > 0) {
1041
            char *cp = (char*)target_saddr;
1042

    
1043
            if ( cp[len-1] && !cp[len] )
1044
                len++;
1045
        }
1046
        if (len > unix_maxlen)
1047
            len = unix_maxlen;
1048
    }
1049

    
1050
    memcpy(addr, target_saddr, len);
1051
    addr->sa_family = sa_family;
1052
    unlock_user(target_saddr, target_addr, 0);
1053

    
1054
    return 0;
1055
}
1056

    
1057
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1058
                                               struct sockaddr *addr,
1059
                                               socklen_t len)
1060
{
1061
    struct target_sockaddr *target_saddr;
1062

    
1063
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1064
    if (!target_saddr)
1065
        return -TARGET_EFAULT;
1066
    memcpy(target_saddr, addr, len);
1067
    target_saddr->sa_family = tswap16(addr->sa_family);
1068
    unlock_user(target_saddr, target_addr, len);
1069

    
1070
    return 0;
1071
}
1072

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

    
1091
    while (cmsg && target_cmsg) {
1092
        void *data = CMSG_DATA(cmsg);
1093
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1094

    
1095
        int len = tswapl(target_cmsg->cmsg_len)
1096
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1097

    
1098
        space += CMSG_SPACE(len);
1099
        if (space > msgh->msg_controllen) {
1100
            space -= CMSG_SPACE(len);
1101
            gemu_log("Host cmsg overflow\n");
1102
            break;
1103
        }
1104

    
1105
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1106
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1107
        cmsg->cmsg_len = CMSG_LEN(len);
1108

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

    
1117
            for (i = 0; i < numfds; i++)
1118
                fd[i] = tswap32(target_fd[i]);
1119
        }
1120

    
1121
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1122
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1123
    }
1124
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1125
 the_end:
1126
    msgh->msg_controllen = space;
1127
    return 0;
1128
}
1129

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

    
1140
    msg_controllen = tswapl(target_msgh->msg_controllen);
1141
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1142
        goto the_end;
1143
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1144
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1145
    if (!target_cmsg)
1146
        return -TARGET_EFAULT;
1147

    
1148
    while (cmsg && target_cmsg) {
1149
        void *data = CMSG_DATA(cmsg);
1150
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1151

    
1152
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1153

    
1154
        space += TARGET_CMSG_SPACE(len);
1155
        if (space > msg_controllen) {
1156
            space -= TARGET_CMSG_SPACE(len);
1157
            gemu_log("Target cmsg overflow\n");
1158
            break;
1159
        }
1160

    
1161
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1162
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1163
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1164

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

    
1173
            for (i = 0; i < numfds; i++)
1174
                target_fd[i] = tswap32(fd[i]);
1175
        }
1176

    
1177
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1178
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1179
    }
1180
    unlock_user(target_cmsg, target_cmsg_addr, space);
1181
 the_end:
1182
    target_msgh->msg_controllen = tswapl(space);
1183
    return 0;
1184
}
1185

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

    
1195
    switch(level) {
1196
    case SOL_TCP:
1197
        /* TCP options all take an 'int' value.  */
1198
        if (optlen < sizeof(uint32_t))
1199
            return -TARGET_EINVAL;
1200

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

    
1238
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1239
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1240
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1241
            break;
1242

    
1243
        case IP_BLOCK_SOURCE:
1244
        case IP_UNBLOCK_SOURCE:
1245
        case IP_ADD_SOURCE_MEMBERSHIP:
1246
        case IP_DROP_SOURCE_MEMBERSHIP:
1247
            if (optlen != sizeof (struct target_ip_mreq_source))
1248
                return -TARGET_EINVAL;
1249

    
1250
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1251
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1252
            unlock_user (ip_mreq_source, optval_addr, 0);
1253
            break;
1254

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

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

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

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

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

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

    
1466
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1467
                             int count, int copy)
1468
{
1469
    struct target_iovec *target_vec;
1470
    abi_ulong base;
1471
    int i;
1472

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

    
1484
    return 0;
1485
}
1486

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

    
1517
/* do_bind() Must return target values and target errnos. */
1518
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1519
                        socklen_t addrlen)
1520
{
1521
    void *addr;
1522
    abi_long ret;
1523

    
1524
    if (addrlen < 0)
1525
        return -TARGET_EINVAL;
1526

    
1527
    addr = alloca(addrlen+1);
1528

    
1529
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1530
    if (ret)
1531
        return ret;
1532

    
1533
    return get_errno(bind(sockfd, addr, addrlen));
1534
}
1535

    
1536
/* do_connect() Must return target values and target errnos. */
1537
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1538
                           socklen_t addrlen)
1539
{
1540
    void *addr;
1541
    abi_long ret;
1542

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

    
1546
    addr = alloca(addrlen);
1547

    
1548
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1549
    if (ret)
1550
        return ret;
1551

    
1552
    return get_errno(connect(sockfd, addr, addrlen));
1553
}
1554

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

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

    
1589
    count = tswapl(msgp->msg_iovlen);
1590
    vec = alloca(count * sizeof(struct iovec));
1591
    target_vec = tswapl(msgp->msg_iov);
1592
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1593
    msg.msg_iovlen = count;
1594
    msg.msg_iov = vec;
1595

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

    
1614
/* do_accept() Must return target values and target errnos. */
1615
static abi_long do_accept(int fd, abi_ulong target_addr,
1616
                          abi_ulong target_addrlen_addr)
1617
{
1618
    socklen_t addrlen;
1619
    void *addr;
1620
    abi_long ret;
1621

    
1622
    if (target_addr == 0)
1623
       return get_errno(accept(fd, NULL, NULL));
1624

    
1625
    /* linux returns EINVAL if addrlen pointer is invalid */
1626
    if (get_user_u32(addrlen, target_addrlen_addr))
1627
        return -TARGET_EINVAL;
1628

    
1629
    if (addrlen < 0)
1630
        return -TARGET_EINVAL;
1631

    
1632
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1633
        return -TARGET_EINVAL;
1634

    
1635
    addr = alloca(addrlen);
1636

    
1637
    ret = get_errno(accept(fd, addr, &addrlen));
1638
    if (!is_error(ret)) {
1639
        host_to_target_sockaddr(target_addr, addr, addrlen);
1640
        if (put_user_u32(addrlen, target_addrlen_addr))
1641
            ret = -TARGET_EFAULT;
1642
    }
1643
    return ret;
1644
}
1645

    
1646
/* do_getpeername() Must return target values and target errnos. */
1647
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1648
                               abi_ulong target_addrlen_addr)
1649
{
1650
    socklen_t addrlen;
1651
    void *addr;
1652
    abi_long ret;
1653

    
1654
    if (get_user_u32(addrlen, target_addrlen_addr))
1655
        return -TARGET_EFAULT;
1656

    
1657
    if (addrlen < 0)
1658
        return -TARGET_EINVAL;
1659

    
1660
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1661
        return -TARGET_EFAULT;
1662

    
1663
    addr = alloca(addrlen);
1664

    
1665
    ret = get_errno(getpeername(fd, addr, &addrlen));
1666
    if (!is_error(ret)) {
1667
        host_to_target_sockaddr(target_addr, addr, addrlen);
1668
        if (put_user_u32(addrlen, target_addrlen_addr))
1669
            ret = -TARGET_EFAULT;
1670
    }
1671
    return ret;
1672
}
1673

    
1674
/* do_getsockname() Must return target values and target errnos. */
1675
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1676
                               abi_ulong target_addrlen_addr)
1677
{
1678
    socklen_t addrlen;
1679
    void *addr;
1680
    abi_long ret;
1681

    
1682
    if (get_user_u32(addrlen, target_addrlen_addr))
1683
        return -TARGET_EFAULT;
1684

    
1685
    if (addrlen < 0)
1686
        return -TARGET_EINVAL;
1687

    
1688
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1689
        return -TARGET_EFAULT;
1690

    
1691
    addr = alloca(addrlen);
1692

    
1693
    ret = get_errno(getsockname(fd, addr, &addrlen));
1694
    if (!is_error(ret)) {
1695
        host_to_target_sockaddr(target_addr, addr, addrlen);
1696
        if (put_user_u32(addrlen, target_addrlen_addr))
1697
            ret = -TARGET_EFAULT;
1698
    }
1699
    return ret;
1700
}
1701

    
1702
/* do_socketpair() Must return target values and target errnos. */
1703
static abi_long do_socketpair(int domain, int type, int protocol,
1704
                              abi_ulong target_tab_addr)
1705
{
1706
    int tab[2];
1707
    abi_long ret;
1708

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

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

    
1726
    if (addrlen < 0)
1727
        return -TARGET_EINVAL;
1728

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

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

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

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

    
1798
    switch(num) {
1799
    case SOCKOP_socket:
1800
        {
1801
            abi_ulong domain, type, protocol;
1802

    
1803
            if (get_user_ual(domain, vptr)
1804
                || get_user_ual(type, vptr + n)
1805
                || get_user_ual(protocol, vptr + 2 * n))
1806
                return -TARGET_EFAULT;
1807

    
1808
            ret = do_socket(domain, type, protocol);
1809
        }
1810
        break;
1811
    case SOCKOP_bind:
1812
        {
1813
            abi_ulong sockfd;
1814
            abi_ulong target_addr;
1815
            socklen_t addrlen;
1816

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

    
1822
            ret = do_bind(sockfd, target_addr, addrlen);
1823
        }
1824
        break;
1825
    case SOCKOP_connect:
1826
        {
1827
            abi_ulong sockfd;
1828
            abi_ulong target_addr;
1829
            socklen_t addrlen;
1830

    
1831
            if (get_user_ual(sockfd, vptr)
1832
                || get_user_ual(target_addr, vptr + n)
1833
                || get_user_ual(addrlen, vptr + 2 * n))
1834
                return -TARGET_EFAULT;
1835

    
1836
            ret = do_connect(sockfd, target_addr, addrlen);
1837
        }
1838
        break;
1839
    case SOCKOP_listen:
1840
        {
1841
            abi_ulong sockfd, backlog;
1842

    
1843
            if (get_user_ual(sockfd, vptr)
1844
                || get_user_ual(backlog, vptr + n))
1845
                return -TARGET_EFAULT;
1846

    
1847
            ret = get_errno(listen(sockfd, backlog));
1848
        }
1849
        break;
1850
    case SOCKOP_accept:
1851
        {
1852
            abi_ulong sockfd;
1853
            abi_ulong target_addr, target_addrlen;
1854

    
1855
            if (get_user_ual(sockfd, vptr)
1856
                || get_user_ual(target_addr, vptr + n)
1857
                || get_user_ual(target_addrlen, vptr + 2 * n))
1858
                return -TARGET_EFAULT;
1859

    
1860
            ret = do_accept(sockfd, target_addr, target_addrlen);
1861
        }
1862
        break;
1863
    case SOCKOP_getsockname:
1864
        {
1865
            abi_ulong sockfd;
1866
            abi_ulong target_addr, target_addrlen;
1867

    
1868
            if (get_user_ual(sockfd, vptr)
1869
                || get_user_ual(target_addr, vptr + n)
1870
                || get_user_ual(target_addrlen, vptr + 2 * n))
1871
                return -TARGET_EFAULT;
1872

    
1873
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1874
        }
1875
        break;
1876
    case SOCKOP_getpeername:
1877
        {
1878
            abi_ulong sockfd;
1879
            abi_ulong target_addr, target_addrlen;
1880

    
1881
            if (get_user_ual(sockfd, vptr)
1882
                || get_user_ual(target_addr, vptr + n)
1883
                || get_user_ual(target_addrlen, vptr + 2 * n))
1884
                return -TARGET_EFAULT;
1885

    
1886
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1887
        }
1888
        break;
1889
    case SOCKOP_socketpair:
1890
        {
1891
            abi_ulong domain, type, protocol;
1892
            abi_ulong tab;
1893

    
1894
            if (get_user_ual(domain, vptr)
1895
                || get_user_ual(type, vptr + n)
1896
                || get_user_ual(protocol, vptr + 2 * n)
1897
                || get_user_ual(tab, vptr + 3 * n))
1898
                return -TARGET_EFAULT;
1899

    
1900
            ret = do_socketpair(domain, type, protocol, tab);
1901
        }
1902
        break;
1903
    case SOCKOP_send:
1904
        {
1905
            abi_ulong sockfd;
1906
            abi_ulong msg;
1907
            size_t len;
1908
            abi_ulong flags;
1909

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

    
1916
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1917
        }
1918
        break;
1919
    case SOCKOP_recv:
1920
        {
1921
            abi_ulong sockfd;
1922
            abi_ulong msg;
1923
            size_t len;
1924
            abi_ulong flags;
1925

    
1926
            if (get_user_ual(sockfd, vptr)
1927
                || get_user_ual(msg, vptr + n)
1928
                || get_user_ual(len, vptr + 2 * n)
1929
                || get_user_ual(flags, vptr + 3 * n))
1930
                return -TARGET_EFAULT;
1931

    
1932
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1933
        }
1934
        break;
1935
    case SOCKOP_sendto:
1936
        {
1937
            abi_ulong sockfd;
1938
            abi_ulong msg;
1939
            size_t len;
1940
            abi_ulong flags;
1941
            abi_ulong addr;
1942
            socklen_t addrlen;
1943

    
1944
            if (get_user_ual(sockfd, vptr)
1945
                || get_user_ual(msg, vptr + n)
1946
                || get_user_ual(len, vptr + 2 * n)
1947
                || get_user_ual(flags, vptr + 3 * n)
1948
                || get_user_ual(addr, vptr + 4 * n)
1949
                || get_user_ual(addrlen, vptr + 5 * n))
1950
                return -TARGET_EFAULT;
1951

    
1952
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1953
        }
1954
        break;
1955
    case SOCKOP_recvfrom:
1956
        {
1957
            abi_ulong sockfd;
1958
            abi_ulong msg;
1959
            size_t len;
1960
            abi_ulong flags;
1961
            abi_ulong addr;
1962
            socklen_t addrlen;
1963

    
1964
            if (get_user_ual(sockfd, vptr)
1965
                || get_user_ual(msg, vptr + n)
1966
                || get_user_ual(len, vptr + 2 * n)
1967
                || get_user_ual(flags, vptr + 3 * n)
1968
                || get_user_ual(addr, vptr + 4 * n)
1969
                || get_user_ual(addrlen, vptr + 5 * n))
1970
                return -TARGET_EFAULT;
1971

    
1972
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1973
        }
1974
        break;
1975
    case SOCKOP_shutdown:
1976
        {
1977
            abi_ulong sockfd, how;
1978

    
1979
            if (get_user_ual(sockfd, vptr)
1980
                || get_user_ual(how, vptr + n))
1981
                return -TARGET_EFAULT;
1982

    
1983
            ret = get_errno(shutdown(sockfd, how));
1984
        }
1985
        break;
1986
    case SOCKOP_sendmsg:
1987
    case SOCKOP_recvmsg:
1988
        {
1989
            abi_ulong fd;
1990
            abi_ulong target_msg;
1991
            abi_ulong flags;
1992

    
1993
            if (get_user_ual(fd, vptr)
1994
                || get_user_ual(target_msg, vptr + n)
1995
                || get_user_ual(flags, vptr + 2 * n))
1996
                return -TARGET_EFAULT;
1997

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

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

    
2017
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2018
        }
2019
        break;
2020
    case SOCKOP_getsockopt:
2021
        {
2022
            abi_ulong sockfd;
2023
            abi_ulong level;
2024
            abi_ulong optname;
2025
            abi_ulong optval;
2026
            socklen_t optlen;
2027

    
2028
            if (get_user_ual(sockfd, vptr)
2029
                || get_user_ual(level, vptr + n)
2030
                || get_user_ual(optname, vptr + 2 * n)
2031
                || get_user_ual(optval, vptr + 3 * n)
2032
                || get_user_ual(optlen, vptr + 4 * n))
2033
                return -TARGET_EFAULT;
2034

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

    
2047
#define N_SHM_REGIONS        32
2048

    
2049
static struct shm_region {
2050
    abi_ulong        start;
2051
    abi_ulong        size;
2052
} shm_regions[N_SHM_REGIONS];
2053

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

    
2069
struct target_semid_ds
2070
{
2071
  struct target_ipc_perm sem_perm;
2072
  abi_ulong sem_otime;
2073
  abi_ulong __unused1;
2074
  abi_ulong sem_ctime;
2075
  abi_ulong __unused2;
2076
  abi_ulong sem_nsems;
2077
  abi_ulong __unused3;
2078
  abi_ulong __unused4;
2079
};
2080

    
2081
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2082
                                               abi_ulong target_addr)
2083
{
2084
    struct target_ipc_perm *target_ip;
2085
    struct target_semid_ds *target_sd;
2086

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

    
2100
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2101
                                               struct ipc_perm *host_ip)
2102
{
2103
    struct target_ipc_perm *target_ip;
2104
    struct target_semid_ds *target_sd;
2105

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

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

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

    
2135
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2136
                                               struct semid_ds *host_sd)
2137
{
2138
    struct target_semid_ds *target_sd;
2139

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

    
2151
struct target_seminfo {
2152
    int semmap;
2153
    int semmni;
2154
    int semmns;
2155
    int semmnu;
2156
    int semmsl;
2157
    int semopm;
2158
    int semume;
2159
    int semusz;
2160
    int semvmx;
2161
    int semaem;
2162
};
2163

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

    
2184
union semun {
2185
        int val;
2186
        struct semid_ds *buf;
2187
        unsigned short *array;
2188
        struct seminfo *__buf;
2189
};
2190

    
2191
union target_semun {
2192
        int val;
2193
        abi_ulong buf;
2194
        abi_ulong array;
2195
        abi_ulong __buf;
2196
};
2197

    
2198
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2199
                                               abi_ulong target_addr)
2200
{
2201
    int nsems;
2202
    unsigned short *array;
2203
    union semun semun;
2204
    struct semid_ds semid_ds;
2205
    int i, ret;
2206

    
2207
    semun.buf = &semid_ds;
2208

    
2209
    ret = semctl(semid, 0, IPC_STAT, semun);
2210
    if (ret == -1)
2211
        return get_errno(ret);
2212

    
2213
    nsems = semid_ds.sem_nsems;
2214

    
2215
    *host_array = malloc(nsems*sizeof(unsigned short));
2216
    array = lock_user(VERIFY_READ, target_addr,
2217
                      nsems*sizeof(unsigned short), 1);
2218
    if (!array)
2219
        return -TARGET_EFAULT;
2220

    
2221
    for(i=0; i<nsems; i++) {
2222
        __get_user((*host_array)[i], &array[i]);
2223
    }
2224
    unlock_user(array, target_addr, 0);
2225

    
2226
    return 0;
2227
}
2228

    
2229
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2230
                                               unsigned short **host_array)
2231
{
2232
    int nsems;
2233
    unsigned short *array;
2234
    union semun semun;
2235
    struct semid_ds semid_ds;
2236
    int i, ret;
2237

    
2238
    semun.buf = &semid_ds;
2239

    
2240
    ret = semctl(semid, 0, IPC_STAT, semun);
2241
    if (ret == -1)
2242
        return get_errno(ret);
2243

    
2244
    nsems = semid_ds.sem_nsems;
2245

    
2246
    array = lock_user(VERIFY_WRITE, target_addr,
2247
                      nsems*sizeof(unsigned short), 0);
2248
    if (!array)
2249
        return -TARGET_EFAULT;
2250

    
2251
    for(i=0; i<nsems; i++) {
2252
        __put_user((*host_array)[i], &array[i]);
2253
    }
2254
    free(*host_array);
2255
    unlock_user(array, target_addr, 1);
2256

    
2257
    return 0;
2258
}
2259

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

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

    
2317
    return ret;
2318
}
2319

    
2320
struct target_sembuf {
2321
    unsigned short sem_num;
2322
    short sem_op;
2323
    short sem_flg;
2324
};
2325

    
2326
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2327
                                             abi_ulong target_addr,
2328
                                             unsigned nsops)
2329
{
2330
    struct target_sembuf *target_sembuf;
2331
    int i;
2332

    
2333
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2334
                              nsops*sizeof(struct target_sembuf), 1);
2335
    if (!target_sembuf)
2336
        return -TARGET_EFAULT;
2337

    
2338
    for(i=0; i<nsops; i++) {
2339
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2340
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2341
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2342
    }
2343

    
2344
    unlock_user(target_sembuf, target_addr, 0);
2345

    
2346
    return 0;
2347
}
2348

    
2349
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2350
{
2351
    struct sembuf sops[nsops];
2352

    
2353
    if (target_to_host_sembuf(sops, ptr, nsops))
2354
        return -TARGET_EFAULT;
2355

    
2356
    return semop(semid, sops, nsops);
2357
}
2358

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

    
2383
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2384
                                               abi_ulong target_addr)
2385
{
2386
    struct target_msqid_ds *target_md;
2387

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

    
2404
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2405
                                               struct msqid_ds *host_md)
2406
{
2407
    struct target_msqid_ds *target_md;
2408

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

    
2425
struct target_msginfo {
2426
    int msgpool;
2427
    int msgmap;
2428
    int msgmax;
2429
    int msgmnb;
2430
    int msgmni;
2431
    int msgssz;
2432
    int msgtql;
2433
    unsigned short int msgseg;
2434
};
2435

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

    
2454
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2455
{
2456
    struct msqid_ds dsarg;
2457
    struct msginfo msginfo;
2458
    abi_long ret = -TARGET_EINVAL;
2459

    
2460
    cmd &= 0xff;
2461

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

    
2483
    return ret;
2484
}
2485

    
2486
struct target_msgbuf {
2487
    abi_long mtype;
2488
    char        mtext[1];
2489
};
2490

    
2491
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2492
                                 unsigned int msgsz, int msgflg)
2493
{
2494
    struct target_msgbuf *target_mb;
2495
    struct msgbuf *host_mb;
2496
    abi_long ret = 0;
2497

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

    
2507
    return ret;
2508
}
2509

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

    
2519
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2520
        return -TARGET_EFAULT;
2521

    
2522
    host_mb = malloc(msgsz+sizeof(long));
2523
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2524

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

    
2536
    target_mb->mtype = tswapl(host_mb->mtype);
2537
    free(host_mb);
2538

    
2539
end:
2540
    if (target_mb)
2541
        unlock_user_struct(target_mb, msgp, 1);
2542
    return ret;
2543
}
2544

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

    
2568
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2569
                                               abi_ulong target_addr)
2570
{
2571
    struct target_shmid_ds *target_sd;
2572

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

    
2588
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2589
                                               struct shmid_ds *host_sd)
2590
{
2591
    struct target_shmid_ds *target_sd;
2592

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

    
2608
struct  target_shminfo {
2609
    abi_ulong shmmax;
2610
    abi_ulong shmmin;
2611
    abi_ulong shmmni;
2612
    abi_ulong shmseg;
2613
    abi_ulong shmall;
2614
};
2615

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

    
2631
struct target_shm_info {
2632
    int used_ids;
2633
    abi_ulong shm_tot;
2634
    abi_ulong shm_rss;
2635
    abi_ulong shm_swp;
2636
    abi_ulong swap_attempts;
2637
    abi_ulong swap_successes;
2638
};
2639

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

    
2656
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2657
{
2658
    struct shmid_ds dsarg;
2659
    struct shminfo shminfo;
2660
    struct shm_info shm_info;
2661
    abi_long ret = -TARGET_EINVAL;
2662

    
2663
    cmd &= 0xff;
2664

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

    
2692
    return ret;
2693
}
2694

    
2695
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2696
{
2697
    abi_long raddr;
2698
    void *host_raddr;
2699
    struct shmid_ds shm_info;
2700
    int i,ret;
2701

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

    
2709
    mmap_lock();
2710

    
2711
    if (shmaddr)
2712
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2713
    else {
2714
        abi_ulong mmap_start;
2715

    
2716
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2717

    
2718
        if (mmap_start == -1) {
2719
            errno = ENOMEM;
2720
            host_raddr = (void *)-1;
2721
        } else
2722
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2723
    }
2724

    
2725
    if (host_raddr == (void *)-1) {
2726
        mmap_unlock();
2727
        return get_errno((long)host_raddr);
2728
    }
2729
    raddr=h2g((unsigned long)host_raddr);
2730

    
2731
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2732
                   PAGE_VALID | PAGE_READ |
2733
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2734

    
2735
    for (i = 0; i < N_SHM_REGIONS; i++) {
2736
        if (shm_regions[i].start == 0) {
2737
            shm_regions[i].start = raddr;
2738
            shm_regions[i].size = shm_info.shm_segsz;
2739
            break;
2740
        }
2741
    }
2742

    
2743
    mmap_unlock();
2744
    return raddr;
2745

    
2746
}
2747

    
2748
static inline abi_long do_shmdt(abi_ulong shmaddr)
2749
{
2750
    int i;
2751

    
2752
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2753
        if (shm_regions[i].start == shmaddr) {
2754
            shm_regions[i].start = 0;
2755
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2756
            break;
2757
        }
2758
    }
2759

    
2760
    return get_errno(shmdt(g2h(shmaddr)));
2761
}
2762

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

    
2773
    version = call >> 16;
2774
    call &= 0xffff;
2775

    
2776
    switch (call) {
2777
    case IPCOP_semop:
2778
        ret = do_semop(first, ptr, second);
2779
        break;
2780

    
2781
    case IPCOP_semget:
2782
        ret = get_errno(semget(first, second, third));
2783
        break;
2784

    
2785
    case IPCOP_semctl:
2786
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2787
        break;
2788

    
2789
    case IPCOP_msgget:
2790
        ret = get_errno(msgget(first, second));
2791
        break;
2792

    
2793
    case IPCOP_msgsnd:
2794
        ret = do_msgsnd(first, ptr, second, third);
2795
        break;
2796

    
2797
    case IPCOP_msgctl:
2798
        ret = do_msgctl(first, second, ptr);
2799
        break;
2800

    
2801
    case IPCOP_msgrcv:
2802
        switch (version) {
2803
        case 0:
2804
            {
2805
                struct target_ipc_kludge {
2806
                    abi_long msgp;
2807
                    abi_long msgtyp;
2808
                } *tmp;
2809

    
2810
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2811
                    ret = -TARGET_EFAULT;
2812
                    break;
2813
                }
2814

    
2815
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2816

    
2817
                unlock_user_struct(tmp, ptr, 0);
2818
                break;
2819
            }
2820
        default:
2821
            ret = do_msgrcv(first, ptr, second, fifth, third);
2822
        }
2823
        break;
2824

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

    
2846
    case IPCOP_shmget:
2847
        /* IPC_* flag values are the same on all linux platforms */
2848
        ret = get_errno(shmget(first, second, third));
2849
        break;
2850

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

    
2864
/* kernel structure types definitions */
2865
#define IFNAMSIZ        16
2866

    
2867
#define STRUCT(name, ...) STRUCT_ ## name,
2868
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2869
enum {
2870
#include "syscall_types.h"
2871
};
2872
#undef STRUCT
2873
#undef STRUCT_SPECIAL
2874

    
2875
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2876
#define STRUCT_SPECIAL(name)
2877
#include "syscall_types.h"
2878
#undef STRUCT
2879
#undef STRUCT_SPECIAL
2880

    
2881
typedef struct IOCTLEntry {
2882
    unsigned int target_cmd;
2883
    unsigned int host_cmd;
2884
    const char *name;
2885
    int access;
2886
    const argtype arg_type[5];
2887
} IOCTLEntry;
2888

    
2889
#define IOC_R 0x0001
2890
#define IOC_W 0x0002
2891
#define IOC_RW (IOC_R | IOC_W)
2892

    
2893
#define MAX_STRUCT_SIZE 4096
2894

    
2895
static IOCTLEntry ioctl_entries[] = {
2896
#define IOCTL(cmd, access, ...) \
2897
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2898
#include "ioctls.h"
2899
    { 0, 0, },
2900
};
2901

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

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

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

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

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

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

    
3086
static void target_to_host_termios (void *dst, const void *src)
3087
{
3088
    struct host_termios *host = dst;
3089
    const struct target_termios *target = src;
3090

    
3091
    host->c_iflag =
3092
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3093
    host->c_oflag =
3094
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3095
    host->c_cflag =
3096
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3097
    host->c_lflag =
3098
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3099
    host->c_line = target->c_line;
3100

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

    
3121
static void host_to_target_termios (void *dst, const void *src)
3122
{
3123
    struct target_termios *target = dst;
3124
    const struct host_termios *host = src;
3125

    
3126
    target->c_iflag =
3127
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3128
    target->c_oflag =
3129
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3130
    target->c_cflag =
3131
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3132
    target->c_lflag =
3133
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3134
    target->c_line = host->c_line;
3135

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

    
3156
static const StructEntry struct_termios_def = {
3157
    .convert = { host_to_target_termios, target_to_host_termios },
3158
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3159
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3160
};
3161

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

    
3174
#if defined(TARGET_I386)
3175

    
3176
/* NOTE: there is really one LDT for all the threads */
3177
static uint8_t *ldt_table;
3178

    
3179
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3180
{
3181
    int size;
3182
    void *p;
3183

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

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

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

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

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

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

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

    
3290
/* specific and weird i386 syscalls */
3291
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3292
                              unsigned long bytecount)
3293
{
3294
    abi_long ret;
3295

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

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

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

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

    
3357
    if (contents == 3) {
3358
        if (seg_not_present == 0)
3359
            return -TARGET_EINVAL;
3360
    }
3361

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

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

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

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

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

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

    
3482
#endif /* defined(TARGET_I386) */
3483

    
3484
#if defined(CONFIG_USE_NPTL)
3485

    
3486
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3487

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

    
3500
static void *clone_func(void *arg)
3501
{
3502
    new_thread_info *info = arg;
3503
    CPUState *env;
3504
    TaskState *ts;
3505

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

    
3534
static int clone_func(void *arg)
3535
{
3536
    CPUState *env = arg;
3537
    cpu_loop(env);
3538
    /* never exits */
3539
    return 0;
3540
}
3541
#endif
3542

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

    
3558
    /* Emulate vfork() with fork() */
3559
    if (flags & CLONE_VFORK)
3560
        flags &= ~(CLONE_VFORK | CLONE_VM);
3561

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

    
3585
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3586
            ts->child_tidptr = child_tidptr;
3587
        }
3588

    
3589
        if (nptl_flags & CLONE_SETTLS)
3590
            cpu_set_tls (new_env, newtls);
3591

    
3592
        /* Grab a mutex so that thread setup appears atomic.  */
3593
        pthread_mutex_lock(&clone_lock);
3594

    
3595
        memset(&info, 0, sizeof(info));
3596
        pthread_mutex_init(&info.mutex, NULL);
3597
        pthread_mutex_lock(&info.mutex);
3598
        pthread_cond_init(&info.cond, NULL);
3599
        info.env = new_env;
3600
        if (nptl_flags & CLONE_CHILD_SETTID)
3601
            info.child_tidptr = child_tidptr;
3602
        if (nptl_flags & CLONE_PARENT_SETTID)
3603
            info.parent_tidptr = parent_tidptr;
3604

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

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

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

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

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

    
3731
    if (host_cmd == -TARGET_EINVAL)
3732
            return host_cmd;
3733

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

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

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

    
3804
    case TARGET_F_GETFL:
3805
        ret = get_errno(fcntl(fd, host_cmd, arg));
3806
        if (ret >= 0) {
3807
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3808
        }
3809
        break;
3810

    
3811
    case TARGET_F_SETFL:
3812
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3813
        break;
3814

    
3815
    case TARGET_F_SETOWN:
3816
    case TARGET_F_GETOWN:
3817
    case TARGET_F_SETSIG:
3818
    case TARGET_F_GETSIG:
3819
    case TARGET_F_SETLEASE:
3820
    case TARGET_F_GETLEASE:
3821
        ret = get_errno(fcntl(fd, host_cmd, arg));
3822
        break;
3823

    
3824
    default:
3825
        ret = get_errno(fcntl(fd, cmd, arg));
3826
        break;
3827
    }
3828
    return ret;
3829
}
3830

    
3831
#ifdef USE_UID16
3832

    
3833
static inline int high2lowuid(int uid)
3834
{
3835
    if (uid > 65535)
3836
        return 65534;
3837
    else
3838
        return uid;
3839
}
3840

    
3841
static inline int high2lowgid(int gid)
3842
{
3843
    if (gid > 65535)
3844
        return 65534;
3845
    else
3846
        return gid;
3847
}
3848

    
3849
static inline int low2highuid(int uid)
3850
{
3851
    if ((int16_t)uid == -1)
3852
        return -1;
3853
    else
3854
        return uid;
3855
}
3856

    
3857
static inline int low2highgid(int gid)
3858
{
3859
    if ((int16_t)gid == -1)
3860
        return -1;
3861
    else
3862
        return gid;
3863
}
3864

    
3865
#endif /* USE_UID16 */
3866

    
3867
void syscall_init(void)
3868
{
3869
    IOCTLEntry *ie;
3870
    const argtype *arg_type;
3871
    int size;
3872
    int i;
3873

    
3874
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3875
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3876
#include "syscall_types.h"
3877
#undef STRUCT
3878
#undef STRUCT_SPECIAL
3879

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

    
3899
        /* Build target_to_host_errno_table[] table from
3900
         * host_to_target_errno_table[]. */
3901
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3902
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3903

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

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

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

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

    
3966
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3967
                                               abi_ulong target_addr)
3968
{
3969
    struct target_timespec *target_ts;
3970

    
3971
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3972
        return -TARGET_EFAULT;
3973
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3974
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3975
    unlock_user_struct(target_ts, target_addr, 0);
3976
    return 0;
3977
}
3978

    
3979
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3980
                                               struct timespec *host_ts)
3981
{
3982
    struct target_timespec *target_ts;
3983

    
3984
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3985
        return -TARGET_EFAULT;
3986
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3987
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3988
    unlock_user_struct(target_ts, target_addr, 1);
3989
    return 0;
3990
}
3991

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

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

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

    
4053
    return 0;
4054
}
4055
#endif
4056

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

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

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

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

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

    
4167
#ifdef DEBUG
4168
    gemu_log("syscall %d", num);
4169
#endif
4170
    if(do_strace)
4171
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4172

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

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

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

    
4369
            argp = alloca((argc + 1) * sizeof(void *));
4370
            envp = alloca((envc + 1) * sizeof(void *));
4371

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

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

    
4394
            if (!(p = lock_user_string(arg1)))
4395
                goto execve_efault;
4396
            ret = get_errno(execve(p, argp, envp));
4397
            unlock_user(p, arg1, 0);
4398

    
4399
            goto execve_end;
4400

    
4401
        execve_efault:
4402
            ret = -TARGET_EFAULT;
4403

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

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

    
4831
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4832

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

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

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

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

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

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

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

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

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

    
5547
    case TARGET_NR_syslog:
5548
        if (!(p = lock_user_string(arg2)))
5549
            goto efault;
5550
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5551
        unlock_user(p, arg2, 0);
5552
        break;
5553

    
5554
    case TARGET_NR_setitimer:
5555
        {
5556
            struct itimerval value, ovalue, *pvalue;
5557

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

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

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

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

    
5883
            dirp = malloc(count);
5884
            if (!dirp) {
5885
                ret = -TARGET_ENOMEM;
5886
                goto fail;
5887
            }
5888

    
5889
            ret = get_errno(sys_getdents(arg1, dirp, count));
5890
            if (!is_error(ret)) {
5891
                struct linux_dirent *de;
5892
                struct target_dirent *tde;
5893
                int len = ret;
5894
                int reclen, treclen;
5895
                int count1, tnamelen;
5896

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

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

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

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

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

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

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

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

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

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

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

    
6496
                if (put_user_u64 (swcr, arg2))
6497
                        goto efault;
6498
                ret = 0;
6499
            }
6500
            break;
6501

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

    
6524
                if (get_user_u64 (swcr, arg2))
6525
                    goto efault;
6526
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6527
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6528

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

    
6540
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6541
                ret = 0;
6542

    
6543
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6544
                    /* Old exceptions are not signaled.  */
6545
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6546

    
6547
                    /* If any exceptions set by this call, and are unmasked,
6548
                       send a signal.  */
6549
                    /* ??? FIXME */
6550
                }
6551
            }
6552
            break;
6553

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

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

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

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

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

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

    
6806
        cmd = target_to_host_fcntl_cmd(arg2);
6807
        if (cmd == -TARGET_EINVAL)
6808
                return cmd;
6809

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

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

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

    
7013
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7014
    case TARGET_NR_set_tid_address:
7015
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7016
        break;
7017
#endif
7018

    
7019
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7020
    case TARGET_NR_tkill:
7021
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7022
        break;
7023
#endif
7024

    
7025
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7026
    case TARGET_NR_tgkill:
7027
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7028
                        target_to_host_signal(arg3)));
7029
        break;
7030
#endif
7031

    
7032
#ifdef TARGET_NR_set_robust_list
7033
    case TARGET_NR_set_robust_list:
7034
        goto unimplemented_nowarn;
7035
#endif
7036

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

    
7091
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7092
    case TARGET_NR_mq_open:
7093
        {
7094
            struct mq_attr posix_mq_attr;
7095

    
7096
            p = lock_user_string(arg1 - 1);
7097
            if (arg4 != 0)
7098
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7099
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7100
            unlock_user (p, arg1, 0);
7101
        }
7102
        break;
7103

    
7104
    case TARGET_NR_mq_unlink:
7105
        p = lock_user_string(arg1 - 1);
7106
        ret = get_errno(mq_unlink(p));
7107
        unlock_user (p, arg1, 0);
7108
        break;
7109

    
7110
    case TARGET_NR_mq_timedsend:
7111
        {
7112
            struct timespec ts;
7113

    
7114
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7115
            if (arg5 != 0) {
7116
                target_to_host_timespec(&ts, arg5);
7117
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7118
                host_to_target_timespec(arg5, &ts);
7119
            }
7120
            else
7121
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7122
            unlock_user (p, arg2, arg3);
7123
        }
7124
        break;
7125

    
7126
    case TARGET_NR_mq_timedreceive:
7127
        {
7128
            struct timespec ts;
7129
            unsigned int prio;
7130

    
7131
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7132
            if (arg5 != 0) {
7133
                target_to_host_timespec(&ts, arg5);
7134
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7135
                host_to_target_timespec(arg5, &ts);
7136
            }
7137
            else
7138
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7139
            unlock_user (p, arg2, arg3);
7140
            if (arg4 != 0)
7141
                put_user_u32(prio, arg4);
7142
        }
7143
        break;
7144

    
7145
    /* Not implemented for now... */
7146
/*     case TARGET_NR_mq_notify: */
7147
/*         break; */
7148

    
7149
    case TARGET_NR_mq_getsetattr:
7150
        {
7151
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7152
            ret = 0;
7153
            if (arg3 != 0) {
7154
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7155
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7156
            }
7157
            if (arg2 != 0) {
7158
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7159
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7160
            }
7161

    
7162
        }
7163
        break;
7164
#endif
7165

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

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