Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ ed18c5ce

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, 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_ABI_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