Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ d1d9f421

History | View | Annotate | Download (94.8 kB)

1
/*
2
 *  Linux syscalls
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 */
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 <sys/types.h>
31
#include <sys/wait.h>
32
#include <sys/time.h>
33
#include <sys/stat.h>
34
#include <sys/mount.h>
35
#include <sys/resource.h>
36
#include <sys/mman.h>
37
#include <sys/swap.h>
38
#include <signal.h>
39
#include <sched.h>
40
#include <sys/socket.h>
41
#include <sys/uio.h>
42
#include <sys/poll.h>
43
#include <sys/times.h>
44
#include <sys/shm.h>
45
#include <utime.h>
46
#include <sys/sysinfo.h>
47
//#include <sys/user.h>
48
#include <netinet/ip.h>
49
#include <netinet/tcp.h>
50

    
51
#define termios host_termios
52
#define winsize host_winsize
53
#define termio host_termio
54
#define sgttyb host_sgttyb /* same as target */
55
#define tchars host_tchars /* same as target */
56
#define ltchars host_ltchars /* same as target */
57

    
58
#include <linux/termios.h>
59
#include <linux/unistd.h>
60
#include <linux/utsname.h>
61
#include <linux/cdrom.h>
62
#include <linux/hdreg.h>
63
#include <linux/soundcard.h>
64
#include <linux/dirent.h>
65
#include <linux/kd.h>
66

    
67
#include "qemu.h"
68

    
69
//#define DEBUG
70

    
71
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
72
/* 16 bit uid wrappers emulation */
73
#define USE_UID16
74
#endif
75

    
76
//#include <linux/msdos_fs.h>
77
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct dirent [2])
78
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct dirent [2])
79

    
80

    
81
#if defined(__powerpc__)
82
#undef __syscall_nr
83
#undef __sc_loadargs_0
84
#undef __sc_loadargs_1
85
#undef __sc_loadargs_2
86
#undef __sc_loadargs_3
87
#undef __sc_loadargs_4
88
#undef __sc_loadargs_5
89
#undef __sc_asm_input_0
90
#undef __sc_asm_input_1
91
#undef __sc_asm_input_2
92
#undef __sc_asm_input_3
93
#undef __sc_asm_input_4
94
#undef __sc_asm_input_5
95
#undef _syscall0
96
#undef _syscall1
97
#undef _syscall2
98
#undef _syscall3
99
#undef _syscall4
100
#undef _syscall5
101

    
102
/* need to redefine syscalls as Linux kernel defines are incorrect for
103
   the clobber list */
104
/* On powerpc a system call basically clobbers the same registers like a
105
 * function call, with the exception of LR (which is needed for the
106
 * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
107
 * an error return status).
108
 */
109

    
110
#define __syscall_nr(nr, type, name, args...)                                \
111
        unsigned long __sc_ret, __sc_err;                                \
112
        {                                                                \
113
                register unsigned long __sc_0  __asm__ ("r0");                \
114
                register unsigned long __sc_3  __asm__ ("r3");                \
115
                register unsigned long __sc_4  __asm__ ("r4");                \
116
                register unsigned long __sc_5  __asm__ ("r5");                \
117
                register unsigned long __sc_6  __asm__ ("r6");                \
118
                register unsigned long __sc_7  __asm__ ("r7");                \
119
                                                                        \
120
                __sc_loadargs_##nr(name, args);                                \
121
                __asm__ __volatile__                                        \
122
                        ("sc           \n\t"                                \
123
                         "mfcr %0      "                                \
124
                        : "=&r" (__sc_0),                                \
125
                          "=&r" (__sc_3),  "=&r" (__sc_4),                \
126
                          "=&r" (__sc_5),  "=&r" (__sc_6),                \
127
                          "=&r" (__sc_7)                                \
128
                        : __sc_asm_input_##nr                                \
129
                        : "cr0", "ctr", "memory",                        \
130
                          "r8", "r9", "r10","r11", "r12");                \
131
                __sc_ret = __sc_3;                                        \
132
                __sc_err = __sc_0;                                        \
133
        }                                                                \
134
        if (__sc_err & 0x10000000)                                        \
135
        {                                                                \
136
                errno = __sc_ret;                                        \
137
                __sc_ret = -1;                                                \
138
        }                                                                \
139
        return (type) __sc_ret
140

    
141
#define __sc_loadargs_0(name, dummy...)                                        \
142
        __sc_0 = __NR_##name
143
#define __sc_loadargs_1(name, arg1)                                        \
144
        __sc_loadargs_0(name);                                                \
145
        __sc_3 = (unsigned long) (arg1)
146
#define __sc_loadargs_2(name, arg1, arg2)                                \
147
        __sc_loadargs_1(name, arg1);                                        \
148
        __sc_4 = (unsigned long) (arg2)
149
#define __sc_loadargs_3(name, arg1, arg2, arg3)                                \
150
        __sc_loadargs_2(name, arg1, arg2);                                \
151
        __sc_5 = (unsigned long) (arg3)
152
#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)                        \
153
        __sc_loadargs_3(name, arg1, arg2, arg3);                        \
154
        __sc_6 = (unsigned long) (arg4)
155
#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)                \
156
        __sc_loadargs_4(name, arg1, arg2, arg3, arg4);                        \
157
        __sc_7 = (unsigned long) (arg5)
158

    
159
#define __sc_asm_input_0 "0" (__sc_0)
160
#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
161
#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
162
#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
163
#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
164
#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
165

    
166
#define _syscall0(type,name)                                                \
167
type name(void)                                                                \
168
{                                                                        \
169
        __syscall_nr(0, type, name);                                        \
170
}
171

    
172
#define _syscall1(type,name,type1,arg1)                                        \
173
type name(type1 arg1)                                                        \
174
{                                                                        \
175
        __syscall_nr(1, type, name, arg1);                                \
176
}
177

    
178
#define _syscall2(type,name,type1,arg1,type2,arg2)                        \
179
type name(type1 arg1, type2 arg2)                                        \
180
{                                                                        \
181
        __syscall_nr(2, type, name, arg1, arg2);                        \
182
}
183

    
184
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)                \
185
type name(type1 arg1, type2 arg2, type3 arg3)                                \
186
{                                                                        \
187
        __syscall_nr(3, type, name, arg1, arg2, arg3);                        \
188
}
189

    
190
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
191
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)                \
192
{                                                                        \
193
        __syscall_nr(4, type, name, arg1, arg2, arg3, arg4);                \
194
}
195

    
196
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
197
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)        \
198
{                                                                        \
199
        __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);        \
200
}
201
#endif
202

    
203
#define __NR_sys_uname __NR_uname
204
#define __NR_sys_getcwd1 __NR_getcwd
205
#define __NR_sys_statfs __NR_statfs
206
#define __NR_sys_fstatfs __NR_fstatfs
207
#define __NR_sys_getdents __NR_getdents
208
#define __NR_sys_getdents64 __NR_getdents64
209
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
210

    
211
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
212
#define __NR__llseek __NR_lseek
213
#endif
214

    
215
#ifdef __NR_gettid
216
_syscall0(int, gettid)
217
#else
218
static int gettid(void) {
219
    return -ENOSYS;
220
}
221
#endif
222
_syscall1(int,sys_uname,struct new_utsname *,buf)
223
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
224
_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
225
_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
226
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
227
          loff_t *, res, uint, wh);
228
_syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
229
_syscall2(int,sys_fstatfs,int,fd,struct kernel_statfs *,buf)
230
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
231
#ifdef __NR_exit_group
232
_syscall1(int,exit_group,int,error_code)
233
#endif
234

    
235
extern int personality(int);
236
extern int flock(int, int);
237
extern int setfsuid(int);
238
extern int setfsgid(int);
239
extern int setresuid(uid_t, uid_t, uid_t);
240
extern int getresuid(uid_t *, uid_t *, uid_t *);
241
extern int setresgid(gid_t, gid_t, gid_t);
242
extern int getresgid(gid_t *, gid_t *, gid_t *);
243
extern int setgroups(int, gid_t *);
244

    
245
static inline long get_errno(long ret)
246
{
247
    if (ret == -1)
248
        return -errno;
249
    else
250
        return ret;
251
}
252

    
253
static inline int is_error(long ret)
254
{
255
    return (unsigned long)ret >= (unsigned long)(-4096);
256
}
257

    
258
static char *target_brk;
259
static char *target_original_brk;
260

    
261
void target_set_brk(char *new_brk)
262
{
263
    target_brk = new_brk;
264
    target_original_brk = new_brk;
265
}
266

    
267
static long do_brk(char *new_brk)
268
{
269
    char *brk_page;
270
    long mapped_addr;
271
    int        new_alloc_size;
272

    
273
    if (!new_brk)
274
        return (long)target_brk;
275
    if (new_brk < target_original_brk)
276
        return -ENOMEM;
277
    
278
    brk_page = (char *)HOST_PAGE_ALIGN((unsigned long)target_brk);
279

    
280
    /* If the new brk is less than this, set it and we're done... */
281
    if (new_brk < brk_page) {
282
        target_brk = new_brk;
283
            return (long)target_brk;
284
    }
285

    
286
    /* We need to allocate more memory after the brk... */
287
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
288
    mapped_addr = get_errno(target_mmap((unsigned long)brk_page, new_alloc_size, 
289
                                        PROT_READ|PROT_WRITE,
290
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
291
    if (is_error(mapped_addr)) {
292
        return mapped_addr;
293
    } else {
294
        target_brk = new_brk;
295
            return (long)target_brk;
296
    }
297
}
298

    
299
static inline fd_set *target_to_host_fds(fd_set *fds, 
300
                                         target_long *target_fds, int n)
301
{
302
#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
303
    return (fd_set *)target_fds;
304
#else
305
    int i, b;
306
    if (target_fds) {
307
        FD_ZERO(fds);
308
        for(i = 0;i < n; i++) {
309
            b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
310
                 (i & (TARGET_LONG_BITS - 1))) & 1;
311
            if (b)
312
                FD_SET(i, fds);
313
        }
314
        return fds;
315
    } else {
316
        return NULL;
317
    }
318
#endif
319
}
320

    
321
static inline void host_to_target_fds(target_long *target_fds, 
322
                                      fd_set *fds, int n)
323
{
324
#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
325
    /* nothing to do */
326
#else
327
    int i, nw, j, k;
328
    target_long v;
329

    
330
    if (target_fds) {
331
        nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;
332
        k = 0;
333
        for(i = 0;i < nw; i++) {
334
            v = 0;
335
            for(j = 0; j < TARGET_LONG_BITS; j++) {
336
                v |= ((FD_ISSET(k, fds) != 0) << j);
337
                k++;
338
            }
339
            target_fds[i] = tswapl(v);
340
        }
341
    }
342
#endif
343
}
344

    
345
#if defined(__alpha__)
346
#define HOST_HZ 1024
347
#else
348
#define HOST_HZ 100
349
#endif
350

    
351
static inline long host_to_target_clock_t(long ticks)
352
{
353
#if HOST_HZ == TARGET_HZ
354
    return ticks;
355
#else
356
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
357
#endif
358
}
359

    
360
static inline void host_to_target_rusage(struct target_rusage *target_rusage, 
361
                                         const struct rusage *rusage)
362
{
363
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
364
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
365
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
366
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
367
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
368
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
369
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
370
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
371
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
372
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
373
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
374
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
375
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
376
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
377
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
378
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
379
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
380
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
381
}
382

    
383
static inline void target_to_host_timeval(struct timeval *tv, 
384
                                          const struct target_timeval *target_tv)
385
{
386
    tv->tv_sec = tswapl(target_tv->tv_sec);
387
    tv->tv_usec = tswapl(target_tv->tv_usec);
388
}
389

    
390
static inline void host_to_target_timeval(struct target_timeval *target_tv, 
391
                                          const struct timeval *tv)
392
{
393
    target_tv->tv_sec = tswapl(tv->tv_sec);
394
    target_tv->tv_usec = tswapl(tv->tv_usec);
395
}
396

    
397

    
398
static long do_select(long n, 
399
                      target_long *target_rfds, target_long *target_wfds, 
400
                      target_long *target_efds, struct target_timeval *target_tv)
401
{
402
    fd_set rfds, wfds, efds;
403
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
404
    struct timeval tv, *tv_ptr;
405
    long ret;
406

    
407
    rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
408
    wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
409
    efds_ptr = target_to_host_fds(&efds, target_efds, n);
410
            
411
    if (target_tv) {
412
        target_to_host_timeval(&tv, target_tv);
413
        tv_ptr = &tv;
414
    } else {
415
        tv_ptr = NULL;
416
    }
417
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
418
    if (!is_error(ret)) {
419
        host_to_target_fds(target_rfds, rfds_ptr, n);
420
        host_to_target_fds(target_wfds, wfds_ptr, n);
421
        host_to_target_fds(target_efds, efds_ptr, n);
422

    
423
        if (target_tv) {
424
            host_to_target_timeval(target_tv, &tv);
425
        }
426
    }
427
    return ret;
428
}
429

    
430
static inline void target_to_host_sockaddr(struct sockaddr *addr,
431
                                           struct target_sockaddr *target_addr,
432
                                           socklen_t len)
433
{
434
    memcpy(addr, target_addr, len);
435
    addr->sa_family = tswap16(target_addr->sa_family);
436
}
437

    
438
static inline void host_to_target_sockaddr(struct target_sockaddr *target_addr,
439
                                           struct sockaddr *addr,
440
                                           socklen_t len)
441
{
442
    memcpy(target_addr, addr, len);
443
    target_addr->sa_family = tswap16(addr->sa_family);
444
}
445

    
446
static inline void target_to_host_cmsg(struct msghdr *msgh,
447
                                       struct target_msghdr *target_msgh)
448
{
449
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
450
    struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
451
    socklen_t space = 0;
452

    
453
    while (cmsg && target_cmsg) {
454
        void *data = CMSG_DATA(cmsg);
455
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
456

    
457
        int len = tswapl(target_cmsg->cmsg_len) 
458
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
459

    
460
        space += CMSG_SPACE(len);
461
        if (space > msgh->msg_controllen) {
462
            space -= CMSG_SPACE(len);
463
            gemu_log("Host cmsg overflow");
464
            break;
465
        }
466

    
467
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
468
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
469
        cmsg->cmsg_len = CMSG_LEN(len);
470

    
471
        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
472
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
473
            memcpy(data, target_data, len);
474
        } else {
475
            int *fd = (int *)data;
476
            int *target_fd = (int *)target_data;
477
            int i, numfds = len / sizeof(int);
478

    
479
            for (i = 0; i < numfds; i++)
480
                fd[i] = tswap32(target_fd[i]);
481
        }
482

    
483
        cmsg = CMSG_NXTHDR(msgh, cmsg);
484
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
485
    }
486

    
487
    msgh->msg_controllen = space;
488
}
489

    
490
static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
491
                                       struct msghdr *msgh)
492
{
493
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
494
    struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
495
    socklen_t space = 0;
496

    
497
    while (cmsg && target_cmsg) {
498
        void *data = CMSG_DATA(cmsg);
499
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
500

    
501
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
502

    
503
        space += TARGET_CMSG_SPACE(len);
504
        if (space > tswapl(target_msgh->msg_controllen)) {
505
            space -= TARGET_CMSG_SPACE(len);
506
            gemu_log("Target cmsg overflow");
507
            break;
508
        }
509

    
510
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
511
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
512
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
513

    
514
        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
515
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
516
            memcpy(target_data, data, len);
517
        } else {
518
            int *fd = (int *)data;
519
            int *target_fd = (int *)target_data;
520
            int i, numfds = len / sizeof(int);
521

    
522
            for (i = 0; i < numfds; i++)
523
                target_fd[i] = tswap32(fd[i]);
524
        }
525

    
526
        cmsg = CMSG_NXTHDR(msgh, cmsg);
527
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
528
    }
529

    
530
    msgh->msg_controllen = tswapl(space);
531
}
532

    
533
static long do_setsockopt(int sockfd, int level, int optname, 
534
                          void *optval, socklen_t optlen)
535
{
536
    int val, ret;
537
            
538
    switch(level) {
539
    case SOL_TCP:
540
        /* TCP options all take an 'int' value.  */
541
        if (optlen < sizeof(uint32_t))
542
            return -EINVAL;
543
        
544
        if (get_user(val, (uint32_t *)optval))
545
            return -EFAULT;
546
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
547
        break;
548
    case SOL_IP:
549
        switch(optname) {
550
        case IP_HDRINCL:
551
            val = 0;
552
            if (optlen >= sizeof(uint32_t)) {
553
                if (get_user(val, (uint32_t *)optval))
554
                    return -EFAULT;
555
            } else if (optlen >= 1) {
556
                if (get_user(val, (uint8_t *)optval))
557
                    return -EFAULT;
558
            }
559
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
560
            break;
561
        default:
562
            goto unimplemented;
563
        }
564
        break;
565
    case SOL_SOCKET:
566
        switch (optname) {
567
            /* Options with 'int' argument.  */
568
        case SO_DEBUG:
569
        case SO_REUSEADDR:
570
        case SO_TYPE:
571
        case SO_ERROR:
572
        case SO_DONTROUTE:
573
        case SO_BROADCAST:
574
        case SO_SNDBUF:
575
        case SO_RCVBUF:
576
        case SO_KEEPALIVE:
577
        case SO_OOBINLINE:
578
        case SO_NO_CHECK:
579
        case SO_PRIORITY:
580
        case SO_BSDCOMPAT:
581
        case SO_PASSCRED:
582
        case SO_TIMESTAMP:
583
        case SO_RCVLOWAT:
584
        case SO_RCVTIMEO:
585
        case SO_SNDTIMEO:
586
            if (optlen < sizeof(uint32_t))
587
                return -EINVAL;
588
            if (get_user(val, (uint32_t *)optval))
589
                return -EFAULT;
590
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
591
            break;
592
        default:
593
            goto unimplemented;
594
        }
595
        break;
596
    default:
597
    unimplemented:
598
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
599
        ret = -ENOSYS;
600
    }
601
    return ret;
602
}
603

    
604
static long do_getsockopt(int sockfd, int level, int optname, 
605
                          void *optval, socklen_t *optlen)
606
{
607
    int len, lv, val, ret;
608

    
609
    switch(level) {
610
    case SOL_SOCKET:
611
        switch (optname) {
612
        case SO_LINGER:
613
        case SO_RCVTIMEO:
614
        case SO_SNDTIMEO:
615
        case SO_PEERCRED:
616
        case SO_PEERNAME:
617
            /* These don't just return a single integer */
618
            goto unimplemented;
619
        default:
620
            if (get_user(len, optlen))
621
                return -EFAULT;
622
            if (len < 0)
623
                return -EINVAL;
624
            lv = sizeof(int);
625
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
626
            if (ret < 0)
627
                return ret;
628
            val = tswap32(val);
629
            if (len > lv)
630
                len = lv;
631
            if (copy_to_user(optval, &val, len))
632
                return -EFAULT;
633
            if (put_user(len, optlen))
634
                return -EFAULT;
635
            break;
636
        }
637
        break;
638
    default:
639
    unimplemented:
640
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
641
                 level, optname);
642
        ret = -ENOSYS;
643
        break;
644
    }
645
    return ret;
646
}
647

    
648
static long do_socketcall(int num, int32_t *vptr)
649
{
650
    long ret;
651

    
652
    switch(num) {
653
    case SOCKOP_socket:
654
        {
655
            int domain = tswap32(vptr[0]);
656
            int type = tswap32(vptr[1]);
657
            int protocol = tswap32(vptr[2]);
658

    
659
            ret = get_errno(socket(domain, type, protocol));
660
        }
661
        break;
662
    case SOCKOP_bind:
663
        {
664
            int sockfd = tswap32(vptr[0]);
665
            void *target_addr = (void *)tswap32(vptr[1]);
666
            socklen_t addrlen = tswap32(vptr[2]);
667
            void *addr = alloca(addrlen);
668

    
669
            target_to_host_sockaddr(addr, target_addr, addrlen);
670
            ret = get_errno(bind(sockfd, addr, addrlen));
671
        }
672
        break;
673
    case SOCKOP_connect:
674
        {
675
            int sockfd = tswap32(vptr[0]);
676
            void *target_addr = (void *)tswap32(vptr[1]);
677
            socklen_t addrlen = tswap32(vptr[2]);
678
            void *addr = alloca(addrlen);
679

    
680
            target_to_host_sockaddr(addr, target_addr, addrlen);
681
            ret = get_errno(connect(sockfd, addr, addrlen));
682
        }
683
        break;
684
    case SOCKOP_listen:
685
        {
686
            int sockfd = tswap32(vptr[0]);
687
            int backlog = tswap32(vptr[1]);
688

    
689
            ret = get_errno(listen(sockfd, backlog));
690
        }
691
        break;
692
    case SOCKOP_accept:
693
        {
694
            int sockfd = tswap32(vptr[0]);
695
            void *target_addr = (void *)tswap32(vptr[1]);
696
            uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
697
            socklen_t addrlen = tswap32(*target_addrlen);
698
            void *addr = alloca(addrlen);
699

    
700
            ret = get_errno(accept(sockfd, addr, &addrlen));
701
            if (!is_error(ret)) {
702
                host_to_target_sockaddr(target_addr, addr, addrlen);
703
                *target_addrlen = tswap32(addrlen);
704
            }
705
        }
706
        break;
707
    case SOCKOP_getsockname:
708
        {
709
            int sockfd = tswap32(vptr[0]);
710
            void *target_addr = (void *)tswap32(vptr[1]);
711
            uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
712
            socklen_t addrlen = tswap32(*target_addrlen);
713
            void *addr = alloca(addrlen);
714

    
715
            ret = get_errno(getsockname(sockfd, addr, &addrlen));
716
            if (!is_error(ret)) {
717
                host_to_target_sockaddr(target_addr, addr, addrlen);
718
                *target_addrlen = tswap32(addrlen);
719
            }
720
        }
721
        break;
722
    case SOCKOP_getpeername:
723
        {
724
            int sockfd = tswap32(vptr[0]);
725
            void *target_addr = (void *)tswap32(vptr[1]);
726
            uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
727
            socklen_t addrlen = tswap32(*target_addrlen);
728
            void *addr = alloca(addrlen);
729

    
730
            ret = get_errno(getpeername(sockfd, addr, &addrlen));
731
            if (!is_error(ret)) {
732
                host_to_target_sockaddr(target_addr, addr, addrlen);
733
                *target_addrlen = tswap32(addrlen);
734
            }
735
        }
736
        break;
737
    case SOCKOP_socketpair:
738
        {
739
            int domain = tswap32(vptr[0]);
740
            int type = tswap32(vptr[1]);
741
            int protocol = tswap32(vptr[2]);
742
            int32_t *target_tab = (void *)tswap32(vptr[3]);
743
            int tab[2];
744

    
745
            ret = get_errno(socketpair(domain, type, protocol, tab));
746
            if (!is_error(ret)) {
747
                target_tab[0] = tswap32(tab[0]);
748
                target_tab[1] = tswap32(tab[1]);
749
            }
750
        }
751
        break;
752
    case SOCKOP_send:
753
        {
754
            int sockfd = tswap32(vptr[0]);
755
            void *msg = (void *)tswap32(vptr[1]);
756
            size_t len = tswap32(vptr[2]);
757
            int flags = tswap32(vptr[3]);
758

    
759
            ret = get_errno(send(sockfd, msg, len, flags));
760
        }
761
        break;
762
    case SOCKOP_recv:
763
        {
764
            int sockfd = tswap32(vptr[0]);
765
            void *msg = (void *)tswap32(vptr[1]);
766
            size_t len = tswap32(vptr[2]);
767
            int flags = tswap32(vptr[3]);
768

    
769
            ret = get_errno(recv(sockfd, msg, len, flags));
770
        }
771
        break;
772
    case SOCKOP_sendto:
773
        {
774
            int sockfd = tswap32(vptr[0]);
775
            void *msg = (void *)tswap32(vptr[1]);
776
            size_t len = tswap32(vptr[2]);
777
            int flags = tswap32(vptr[3]);
778
            void *target_addr = (void *)tswap32(vptr[4]);
779
            socklen_t addrlen = tswap32(vptr[5]);
780
            void *addr = alloca(addrlen);
781

    
782
            target_to_host_sockaddr(addr, target_addr, addrlen);
783
            ret = get_errno(sendto(sockfd, msg, len, flags, addr, addrlen));
784
        }
785
        break;
786
    case SOCKOP_recvfrom:
787
        {
788
            int sockfd = tswap32(vptr[0]);
789
            void *msg = (void *)tswap32(vptr[1]);
790
            size_t len = tswap32(vptr[2]);
791
            int flags = tswap32(vptr[3]);
792
            void *target_addr = (void *)tswap32(vptr[4]);
793
            uint32_t *target_addrlen = (void *)tswap32(vptr[5]);
794
            socklen_t addrlen = tswap32(*target_addrlen);
795
            void *addr = alloca(addrlen);
796

    
797
            ret = get_errno(recvfrom(sockfd, msg, len, flags, addr, &addrlen));
798
            if (!is_error(ret)) {
799
                host_to_target_sockaddr(target_addr, addr, addrlen);
800
                *target_addrlen = tswap32(addrlen);
801
            }
802
        }
803
        break;
804
    case SOCKOP_shutdown:
805
        {
806
            int sockfd = tswap32(vptr[0]);
807
            int how = tswap32(vptr[1]);
808

    
809
            ret = get_errno(shutdown(sockfd, how));
810
        }
811
        break;
812
    case SOCKOP_sendmsg:
813
    case SOCKOP_recvmsg:
814
        {
815
            int fd;
816
            struct target_msghdr *msgp;
817
            struct msghdr msg;
818
            int flags, count, i;
819
            struct iovec *vec;
820
            struct target_iovec *target_vec;
821

    
822
            msgp = (void *)tswap32(vptr[1]);
823
            msg.msg_name = (void *)tswapl(msgp->msg_name);
824
            msg.msg_namelen = tswapl(msgp->msg_namelen);
825
            msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
826
            msg.msg_control = alloca(msg.msg_controllen);
827
            msg.msg_flags = tswap32(msgp->msg_flags);
828

    
829
            count = tswapl(msgp->msg_iovlen);
830
            vec = alloca(count * sizeof(struct iovec));
831
            target_vec = (void *)tswapl(msgp->msg_iov);
832
            for(i = 0;i < count; i++) {
833
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
834
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
835
            }
836
            msg.msg_iovlen = count;
837
            msg.msg_iov = vec;
838

    
839
            fd = tswap32(vptr[0]);
840
            flags = tswap32(vptr[2]);
841
            if (num == SOCKOP_sendmsg) {
842
                target_to_host_cmsg(&msg, msgp);
843
                ret = get_errno(sendmsg(fd, &msg, flags));
844
            } else {
845
                ret = get_errno(recvmsg(fd, &msg, flags));
846
                if (!is_error(ret))
847
                  host_to_target_cmsg(msgp, &msg);
848
            }
849
        }
850
        break;
851
    case SOCKOP_setsockopt:
852
        {
853
            int sockfd = tswap32(vptr[0]);
854
            int level = tswap32(vptr[1]);
855
            int optname = tswap32(vptr[2]);
856
            void *optval = (void *)tswap32(vptr[3]);
857
            socklen_t optlen = tswap32(vptr[4]);
858

    
859
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
860
        }
861
        break;
862
    case SOCKOP_getsockopt:
863
        {
864
            int sockfd = tswap32(vptr[0]);
865
            int level = tswap32(vptr[1]);
866
            int optname = tswap32(vptr[2]);
867
            void *optval = (void *)tswap32(vptr[3]);
868
            uint32_t *poptlen = (void *)tswap32(vptr[4]);
869

    
870
            ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
871
        }
872
        break;
873
    default:
874
        gemu_log("Unsupported socketcall: %d\n", num);
875
        ret = -ENOSYS;
876
        break;
877
    }
878
    return ret;
879
}
880

    
881

    
882
#define N_SHM_REGIONS        32
883

    
884
static struct shm_region {
885
    uint32_t        start;
886
    uint32_t        size;
887
} shm_regions[N_SHM_REGIONS];
888

    
889
static long do_ipc(long call, long first, long second, long third,
890
                   long ptr, long fifth)
891
{
892
    int version;
893
    long ret = 0;
894
    unsigned long raddr;
895
    struct shmid_ds shm_info;
896
    int i;
897

    
898
    version = call >> 16;
899
    call &= 0xffff;
900

    
901
    switch (call) {
902
    case IPCOP_shmat:
903
        /* SHM_* flags are the same on all linux platforms */
904
        ret = get_errno((long) shmat(first, (void *) ptr, second));
905
        if (is_error(ret))
906
            break;
907
        raddr = ret;
908
        /* find out the length of the shared memory segment */
909
        
910
        ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
911
        if (is_error(ret)) {
912
            /* can't get length, bail out */
913
            shmdt((void *) raddr);
914
            break;
915
        }
916
        page_set_flags(raddr, raddr + shm_info.shm_segsz,
917
                       PAGE_VALID | PAGE_READ |
918
                       ((second & SHM_RDONLY)? 0: PAGE_WRITE));
919
        for (i = 0; i < N_SHM_REGIONS; ++i) {
920
            if (shm_regions[i].start == 0) {
921
                shm_regions[i].start = raddr;
922
                shm_regions[i].size = shm_info.shm_segsz;
923
                break;
924
            }
925
        }
926
        if (put_user(raddr, (uint32_t *)third))
927
            return -EFAULT;
928
        ret = 0;
929
        break;
930
    case IPCOP_shmdt:
931
        for (i = 0; i < N_SHM_REGIONS; ++i) {
932
            if (shm_regions[i].start == ptr) {
933
                shm_regions[i].start = 0;
934
                page_set_flags(ptr, shm_regions[i].size, 0);
935
                break;
936
            }
937
        }
938
        ret = get_errno(shmdt((void *) ptr));
939
        break;
940

    
941
    case IPCOP_shmget:
942
        /* IPC_* flag values are the same on all linux platforms */
943
        ret = get_errno(shmget(first, second, third));
944
        break;
945

    
946
        /* IPC_* and SHM_* command values are the same on all linux platforms */
947
    case IPCOP_shmctl:
948
        switch(second) {
949
        case IPC_RMID:
950
        case SHM_LOCK:
951
        case SHM_UNLOCK:
952
            ret = get_errno(shmctl(first, second, NULL));
953
            break;
954
        default:
955
            goto unimplemented;
956
        }
957
        break;
958
    default:
959
    unimplemented:
960
        gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
961
        ret = -ENOSYS;
962
        break;
963
    }
964
    return ret;
965
}
966

    
967
/* kernel structure types definitions */
968
#define IFNAMSIZ        16
969

    
970
#define STRUCT(name, list...) STRUCT_ ## name,
971
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
972
enum {
973
#include "syscall_types.h"
974
};
975
#undef STRUCT
976
#undef STRUCT_SPECIAL
977

    
978
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
979
#define STRUCT_SPECIAL(name)
980
#include "syscall_types.h"
981
#undef STRUCT
982
#undef STRUCT_SPECIAL
983

    
984
typedef struct IOCTLEntry {
985
    unsigned int target_cmd;
986
    unsigned int host_cmd;
987
    const char *name;
988
    int access;
989
    const argtype arg_type[5];
990
} IOCTLEntry;
991

    
992
#define IOC_R 0x0001
993
#define IOC_W 0x0002
994
#define IOC_RW (IOC_R | IOC_W)
995

    
996
#define MAX_STRUCT_SIZE 4096
997

    
998
IOCTLEntry ioctl_entries[] = {
999
#define IOCTL(cmd, access, types...) \
1000
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
1001
#include "ioctls.h"
1002
    { 0, 0, },
1003
};
1004

    
1005
static long do_ioctl(long fd, long cmd, long arg)
1006
{
1007
    const IOCTLEntry *ie;
1008
    const argtype *arg_type;
1009
    long ret;
1010
    uint8_t buf_temp[MAX_STRUCT_SIZE];
1011

    
1012
    ie = ioctl_entries;
1013
    for(;;) {
1014
        if (ie->target_cmd == 0) {
1015
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
1016
            return -ENOSYS;
1017
        }
1018
        if (ie->target_cmd == cmd)
1019
            break;
1020
        ie++;
1021
    }
1022
    arg_type = ie->arg_type;
1023
#if defined(DEBUG)
1024
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
1025
#endif
1026
    switch(arg_type[0]) {
1027
    case TYPE_NULL:
1028
        /* no argument */
1029
        ret = get_errno(ioctl(fd, ie->host_cmd));
1030
        break;
1031
    case TYPE_PTRVOID:
1032
    case TYPE_INT:
1033
        /* int argment */
1034
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
1035
        break;
1036
    case TYPE_PTR:
1037
        arg_type++;
1038
        switch(ie->access) {
1039
        case IOC_R:
1040
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1041
            if (!is_error(ret)) {
1042
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
1043
            }
1044
            break;
1045
        case IOC_W:
1046
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
1047
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1048
            break;
1049
        default:
1050
        case IOC_RW:
1051
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
1052
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1053
            if (!is_error(ret)) {
1054
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
1055
            }
1056
            break;
1057
        }
1058
        break;
1059
    default:
1060
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
1061
        ret = -ENOSYS;
1062
        break;
1063
    }
1064
    return ret;
1065
}
1066

    
1067
bitmask_transtbl iflag_tbl[] = {
1068
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
1069
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
1070
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
1071
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
1072
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
1073
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
1074
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
1075
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
1076
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
1077
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
1078
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
1079
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
1080
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
1081
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
1082
        { 0, 0, 0, 0 }
1083
};
1084

    
1085
bitmask_transtbl oflag_tbl[] = {
1086
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
1087
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
1088
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
1089
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
1090
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
1091
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
1092
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
1093
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
1094
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
1095
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
1096
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
1097
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
1098
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
1099
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
1100
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
1101
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
1102
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
1103
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
1104
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
1105
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
1106
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
1107
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
1108
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
1109
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
1110
        { 0, 0, 0, 0 }
1111
};
1112

    
1113
bitmask_transtbl cflag_tbl[] = {
1114
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
1115
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
1116
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
1117
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
1118
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
1119
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
1120
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
1121
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
1122
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
1123
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
1124
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
1125
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
1126
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
1127
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
1128
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
1129
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
1130
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
1131
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
1132
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
1133
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
1134
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
1135
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
1136
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
1137
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
1138
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
1139
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
1140
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
1141
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
1142
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
1143
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
1144
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
1145
        { 0, 0, 0, 0 }
1146
};
1147

    
1148
bitmask_transtbl lflag_tbl[] = {
1149
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
1150
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
1151
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
1152
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
1153
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
1154
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
1155
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
1156
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
1157
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
1158
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
1159
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
1160
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
1161
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
1162
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
1163
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
1164
        { 0, 0, 0, 0 }
1165
};
1166

    
1167
static void target_to_host_termios (void *dst, const void *src)
1168
{
1169
    struct host_termios *host = dst;
1170
    const struct target_termios *target = src;
1171
    
1172
    host->c_iflag = 
1173
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1174
    host->c_oflag = 
1175
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1176
    host->c_cflag = 
1177
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1178
    host->c_lflag = 
1179
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
1180
    host->c_line = target->c_line;
1181
    
1182
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 
1183
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 
1184
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];       
1185
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 
1186
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];   
1187
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 
1188
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];   
1189
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 
1190
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];       
1191
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 
1192
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 
1193
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];   
1194
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];   
1195
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];   
1196
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];     
1197
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];       
1198
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 
1199
}
1200
  
1201
static void host_to_target_termios (void *dst, const void *src)
1202
{
1203
    struct target_termios *target = dst;
1204
    const struct host_termios *host = src;
1205

    
1206
    target->c_iflag = 
1207
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1208
    target->c_oflag = 
1209
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1210
    target->c_cflag = 
1211
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1212
    target->c_lflag = 
1213
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
1214
    target->c_line = host->c_line;
1215
  
1216
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
1217
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
1218
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
1219
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
1220
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
1221
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
1222
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
1223
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
1224
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
1225
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
1226
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
1227
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
1228
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
1229
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
1230
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
1231
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
1232
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
1233
}
1234

    
1235
StructEntry struct_termios_def = {
1236
    .convert = { host_to_target_termios, target_to_host_termios },
1237
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
1238
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
1239
};
1240

    
1241
static bitmask_transtbl mmap_flags_tbl[] = {
1242
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
1243
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
1244
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
1245
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
1246
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
1247
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
1248
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
1249
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
1250
        { 0, 0, 0, 0 }
1251
};
1252

    
1253
static bitmask_transtbl fcntl_flags_tbl[] = {
1254
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
1255
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
1256
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
1257
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
1258
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
1259
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
1260
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
1261
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
1262
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
1263
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
1264
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
1265
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
1266
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
1267
#if defined(O_DIRECT)
1268
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
1269
#endif
1270
        { 0, 0, 0, 0 }
1271
};
1272

    
1273
#if defined(TARGET_I386)
1274

    
1275
/* NOTE: there is really one LDT for all the threads */
1276
uint8_t *ldt_table;
1277

    
1278
static int read_ldt(void *ptr, unsigned long bytecount)
1279
{
1280
    int size;
1281

    
1282
    if (!ldt_table)
1283
        return 0;
1284
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
1285
    if (size > bytecount)
1286
        size = bytecount;
1287
    memcpy(ptr, ldt_table, size);
1288
    return size;
1289
}
1290

    
1291
/* XXX: add locking support */
1292
static int write_ldt(CPUX86State *env, 
1293
                     void *ptr, unsigned long bytecount, int oldmode)
1294
{
1295
    struct target_modify_ldt_ldt_s ldt_info;
1296
    int seg_32bit, contents, read_exec_only, limit_in_pages;
1297
    int seg_not_present, useable;
1298
    uint32_t *lp, entry_1, entry_2;
1299

    
1300
    if (bytecount != sizeof(ldt_info))
1301
        return -EINVAL;
1302
    memcpy(&ldt_info, ptr, sizeof(ldt_info));
1303
    tswap32s(&ldt_info.entry_number);
1304
    tswapls((long *)&ldt_info.base_addr);
1305
    tswap32s(&ldt_info.limit);
1306
    tswap32s(&ldt_info.flags);
1307
    
1308
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1309
        return -EINVAL;
1310
    seg_32bit = ldt_info.flags & 1;
1311
    contents = (ldt_info.flags >> 1) & 3;
1312
    read_exec_only = (ldt_info.flags >> 3) & 1;
1313
    limit_in_pages = (ldt_info.flags >> 4) & 1;
1314
    seg_not_present = (ldt_info.flags >> 5) & 1;
1315
    useable = (ldt_info.flags >> 6) & 1;
1316

    
1317
    if (contents == 3) {
1318
        if (oldmode)
1319
            return -EINVAL;
1320
        if (seg_not_present == 0)
1321
            return -EINVAL;
1322
    }
1323
    /* allocate the LDT */
1324
    if (!ldt_table) {
1325
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1326
        if (!ldt_table)
1327
            return -ENOMEM;
1328
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1329
        env->ldt.base = ldt_table;
1330
        env->ldt.limit = 0xffff;
1331
    }
1332

    
1333
    /* NOTE: same code as Linux kernel */
1334
    /* Allow LDTs to be cleared by the user. */
1335
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
1336
        if (oldmode ||
1337
            (contents == 0                &&
1338
             read_exec_only == 1        &&
1339
             seg_32bit == 0                &&
1340
             limit_in_pages == 0        &&
1341
             seg_not_present == 1        &&
1342
             useable == 0 )) {
1343
            entry_1 = 0;
1344
            entry_2 = 0;
1345
            goto install;
1346
        }
1347
    }
1348
    
1349
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
1350
        (ldt_info.limit & 0x0ffff);
1351
    entry_2 = (ldt_info.base_addr & 0xff000000) |
1352
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
1353
        (ldt_info.limit & 0xf0000) |
1354
        ((read_exec_only ^ 1) << 9) |
1355
        (contents << 10) |
1356
        ((seg_not_present ^ 1) << 15) |
1357
        (seg_32bit << 22) |
1358
        (limit_in_pages << 23) |
1359
        0x7000;
1360
    if (!oldmode)
1361
        entry_2 |= (useable << 20);
1362

    
1363
    /* Install the new entry ...  */
1364
install:
1365
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
1366
    lp[0] = tswap32(entry_1);
1367
    lp[1] = tswap32(entry_2);
1368
    return 0;
1369
}
1370

    
1371
/* specific and weird i386 syscalls */
1372
int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
1373
{
1374
    int ret = -ENOSYS;
1375
    
1376
    switch (func) {
1377
    case 0:
1378
        ret = read_ldt(ptr, bytecount);
1379
        break;
1380
    case 1:
1381
        ret = write_ldt(env, ptr, bytecount, 1);
1382
        break;
1383
    case 0x11:
1384
        ret = write_ldt(env, ptr, bytecount, 0);
1385
        break;
1386
    }
1387
    return ret;
1388
}
1389

    
1390
#endif /* defined(TARGET_I386) */
1391

    
1392
/* this stack is the equivalent of the kernel stack associated with a
1393
   thread/process */
1394
#define NEW_STACK_SIZE 8192
1395

    
1396
static int clone_func(void *arg)
1397
{
1398
    CPUState *env = arg;
1399
    cpu_loop(env);
1400
    /* never exits */
1401
    return 0;
1402
}
1403

    
1404
int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
1405
{
1406
    int ret;
1407
    TaskState *ts;
1408
    uint8_t *new_stack;
1409
    CPUState *new_env;
1410
    
1411
    if (flags & CLONE_VM) {
1412
        ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
1413
        memset(ts, 0, sizeof(TaskState));
1414
        new_stack = ts->stack;
1415
        ts->used = 1;
1416
        /* add in task state list */
1417
        ts->next = first_task_state;
1418
        first_task_state = ts;
1419
        /* we create a new CPU instance. */
1420
        new_env = cpu_init();
1421
        memcpy(new_env, env, sizeof(CPUState));
1422
#if defined(TARGET_I386)
1423
        if (!newsp)
1424
            newsp = env->regs[R_ESP];
1425
        new_env->regs[R_ESP] = newsp;
1426
        new_env->regs[R_EAX] = 0;
1427
#elif defined(TARGET_ARM)
1428
        if (!newsp)
1429
            newsp = env->regs[13];
1430
        new_env->regs[13] = newsp;
1431
        new_env->regs[0] = 0;
1432
#elif defined(TARGET_SPARC)
1433
        printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1434
#elif defined(TARGET_PPC)
1435
        if (!newsp)
1436
            newsp = env->gpr[1];
1437
        new_env->gpr[1] = newsp;
1438
        { 
1439
            int i;
1440
            for (i = 7; i < 32; i++)
1441
                new_env->gpr[i] = 0;
1442
        }
1443
#else
1444
#error unsupported target CPU
1445
#endif
1446
        new_env->opaque = ts;
1447
#ifdef __ia64__
1448
        ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1449
#else
1450
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1451
#endif
1452
    } else {
1453
        /* if no CLONE_VM, we consider it is a fork */
1454
        if ((flags & ~CSIGNAL) != 0)
1455
            return -EINVAL;
1456
        ret = fork();
1457
    }
1458
    return ret;
1459
}
1460

    
1461
static long do_fcntl(int fd, int cmd, unsigned long arg)
1462
{
1463
    struct flock fl;
1464
    struct target_flock *target_fl = (void *)arg;
1465
    long ret;
1466
    
1467
    switch(cmd) {
1468
    case TARGET_F_GETLK:
1469
        ret = fcntl(fd, cmd, &fl);
1470
        if (ret == 0) {
1471
            target_fl->l_type = tswap16(fl.l_type);
1472
            target_fl->l_whence = tswap16(fl.l_whence);
1473
            target_fl->l_start = tswapl(fl.l_start);
1474
            target_fl->l_len = tswapl(fl.l_len);
1475
            target_fl->l_pid = tswapl(fl.l_pid);
1476
        }
1477
        break;
1478
        
1479
    case TARGET_F_SETLK:
1480
    case TARGET_F_SETLKW:
1481
        fl.l_type = tswap16(target_fl->l_type);
1482
        fl.l_whence = tswap16(target_fl->l_whence);
1483
        fl.l_start = tswapl(target_fl->l_start);
1484
        fl.l_len = tswapl(target_fl->l_len);
1485
        fl.l_pid = tswapl(target_fl->l_pid);
1486
        ret = fcntl(fd, cmd, &fl);
1487
        break;
1488
        
1489
    case TARGET_F_GETLK64:
1490
    case TARGET_F_SETLK64:
1491
    case TARGET_F_SETLKW64:
1492
        ret = -1;
1493
        errno = EINVAL;
1494
        break;
1495

    
1496
    case F_GETFL:
1497
        ret = fcntl(fd, cmd, arg);
1498
        ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
1499
        break;
1500

    
1501
    case F_SETFL:
1502
        ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl));
1503
        break;
1504

    
1505
    default:
1506
        ret = fcntl(fd, cmd, arg);
1507
        break;
1508
    }
1509
    return ret;
1510
}
1511

    
1512
#ifdef USE_UID16
1513

    
1514
static inline int high2lowuid(int uid)
1515
{
1516
    if (uid > 65535)
1517
        return 65534;
1518
    else
1519
        return uid;
1520
}
1521

    
1522
static inline int high2lowgid(int gid)
1523
{
1524
    if (gid > 65535)
1525
        return 65534;
1526
    else
1527
        return gid;
1528
}
1529

    
1530
static inline int low2highuid(int uid)
1531
{
1532
    if ((int16_t)uid == -1)
1533
        return -1;
1534
    else
1535
        return uid;
1536
}
1537

    
1538
static inline int low2highgid(int gid)
1539
{
1540
    if ((int16_t)gid == -1)
1541
        return -1;
1542
    else
1543
        return gid;
1544
}
1545

    
1546
#endif /* USE_UID16 */
1547

    
1548
void syscall_init(void)
1549
{
1550
    IOCTLEntry *ie;
1551
    const argtype *arg_type;
1552
    int size;
1553

    
1554
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
1555
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 
1556
#include "syscall_types.h"
1557
#undef STRUCT
1558
#undef STRUCT_SPECIAL
1559

    
1560
    /* we patch the ioctl size if necessary. We rely on the fact that
1561
       no ioctl has all the bits at '1' in the size field */
1562
    ie = ioctl_entries;
1563
    while (ie->target_cmd != 0) {
1564
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
1565
            TARGET_IOC_SIZEMASK) {
1566
            arg_type = ie->arg_type;
1567
            if (arg_type[0] != TYPE_PTR) {
1568
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n", 
1569
                        ie->target_cmd);
1570
                exit(1);
1571
            }
1572
            arg_type++;
1573
            size = thunk_type_size(arg_type, 0);
1574
            ie->target_cmd = (ie->target_cmd & 
1575
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
1576
                (size << TARGET_IOC_SIZESHIFT);
1577
        }
1578
        /* automatic consistency check if same arch */
1579
#if defined(__i386__) && defined(TARGET_I386)
1580
        if (ie->target_cmd != ie->host_cmd) {
1581
            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n", 
1582
                    ie->target_cmd, ie->host_cmd);
1583
        }
1584
#endif
1585
        ie++;
1586
    }
1587
}
1588

    
1589
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 
1590
                long arg4, long arg5, long arg6)
1591
{
1592
    long ret;
1593
    struct stat st;
1594
    struct kernel_statfs *stfs;
1595
    
1596
#ifdef DEBUG
1597
    gemu_log("syscall %d", num);
1598
#endif
1599
    switch(num) {
1600
    case TARGET_NR_exit:
1601
#ifdef HAVE_GPROF
1602
        _mcleanup();
1603
#endif
1604
        /* XXX: should free thread stack and CPU env */
1605
        _exit(arg1);
1606
        ret = 0; /* avoid warning */
1607
        break;
1608
    case TARGET_NR_read:
1609
        page_unprotect_range((void *)arg2, arg3);
1610
        ret = get_errno(read(arg1, (void *)arg2, arg3));
1611
        break;
1612
    case TARGET_NR_write:
1613
        ret = get_errno(write(arg1, (void *)arg2, arg3));
1614
        break;
1615
    case TARGET_NR_open:
1616
        ret = get_errno(open(path((const char *)arg1),
1617
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
1618
                             arg3));
1619
        break;
1620
    case TARGET_NR_close:
1621
        ret = get_errno(close(arg1));
1622
        break;
1623
    case TARGET_NR_brk:
1624
        ret = do_brk((char *)arg1);
1625
        break;
1626
    case TARGET_NR_fork:
1627
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
1628
        break;
1629
    case TARGET_NR_waitpid:
1630
        {
1631
            int *status = (int *)arg2;
1632
            ret = get_errno(waitpid(arg1, status, arg3));
1633
            if (!is_error(ret) && status)
1634
                tswapls((long *)&status);
1635
        }
1636
        break;
1637
    case TARGET_NR_creat:
1638
        ret = get_errno(creat((const char *)arg1, arg2));
1639
        break;
1640
    case TARGET_NR_link:
1641
        ret = get_errno(link((const char *)arg1, (const char *)arg2));
1642
        break;
1643
    case TARGET_NR_unlink:
1644
        ret = get_errno(unlink((const char *)arg1));
1645
        break;
1646
    case TARGET_NR_execve:
1647
        {
1648
            char **argp, **envp;
1649
            int argc, envc;
1650
            uint32_t *p;
1651
            char **q;
1652

    
1653
            argc = 0;
1654
            for (p = (void *)arg2; *p; p++)
1655
                argc++;
1656
            envc = 0;
1657
            for (p = (void *)arg3; *p; p++)
1658
                envc++;
1659

    
1660
            argp = alloca((argc + 1) * sizeof(void *));
1661
            envp = alloca((envc + 1) * sizeof(void *));
1662

    
1663
            for (p = (void *)arg2, q = argp; *p; p++, q++)
1664
                *q = (void *)tswap32(*p);
1665
            *q = NULL;
1666

    
1667
            for (p = (void *)arg3, q = envp; *p; p++, q++)
1668
                *q = (void *)tswap32(*p);
1669
            *q = NULL;
1670

    
1671
            ret = get_errno(execve((const char *)arg1, argp, envp));
1672
        }
1673
        break;
1674
    case TARGET_NR_chdir:
1675
        ret = get_errno(chdir((const char *)arg1));
1676
        break;
1677
    case TARGET_NR_time:
1678
        {
1679
            int *time_ptr = (int *)arg1;
1680
            ret = get_errno(time((time_t *)time_ptr));
1681
            if (!is_error(ret) && time_ptr)
1682
                tswap32s(time_ptr);
1683
        }
1684
        break;
1685
    case TARGET_NR_mknod:
1686
        ret = get_errno(mknod((const char *)arg1, arg2, arg3));
1687
        break;
1688
    case TARGET_NR_chmod:
1689
        ret = get_errno(chmod((const char *)arg1, arg2));
1690
        break;
1691
#ifdef TARGET_NR_break
1692
    case TARGET_NR_break:
1693
        goto unimplemented;
1694
#endif
1695
#ifdef TARGET_NR_oldstat
1696
    case TARGET_NR_oldstat:
1697
        goto unimplemented;
1698
#endif
1699
    case TARGET_NR_lseek:
1700
        ret = get_errno(lseek(arg1, arg2, arg3));
1701
        break;
1702
    case TARGET_NR_getpid:
1703
        ret = get_errno(getpid());
1704
        break;
1705
    case TARGET_NR_mount:
1706
        /* need to look at the data field */
1707
        goto unimplemented;
1708
    case TARGET_NR_umount:
1709
        ret = get_errno(umount((const char *)arg1));
1710
        break;
1711
    case TARGET_NR_stime:
1712
        {
1713
            int *time_ptr = (int *)arg1;
1714
            if (time_ptr)
1715
                tswap32s(time_ptr);
1716
            ret = get_errno(stime((time_t *)time_ptr));
1717
        }
1718
        break;
1719
    case TARGET_NR_ptrace:
1720
        goto unimplemented;
1721
    case TARGET_NR_alarm:
1722
        ret = alarm(arg1);
1723
        break;
1724
#ifdef TARGET_NR_oldfstat
1725
    case TARGET_NR_oldfstat:
1726
        goto unimplemented;
1727
#endif
1728
    case TARGET_NR_pause:
1729
        ret = get_errno(pause());
1730
        break;
1731
    case TARGET_NR_utime:
1732
        {
1733
            struct utimbuf tbuf, *tbuf1;
1734
            struct target_utimbuf *target_tbuf = (void *)arg2;
1735
            if (target_tbuf) {
1736
                get_user(tbuf.actime, &target_tbuf->actime);
1737
                get_user(tbuf.modtime, &target_tbuf->modtime);
1738
                tbuf1 = &tbuf;
1739
            } else {
1740
                tbuf1 = NULL;
1741
            }
1742
            ret = get_errno(utime((const char *)arg1, tbuf1));
1743
        }
1744
        break;
1745
#ifdef TARGET_NR_stty
1746
    case TARGET_NR_stty:
1747
        goto unimplemented;
1748
#endif
1749
#ifdef TARGET_NR_gtty
1750
    case TARGET_NR_gtty:
1751
        goto unimplemented;
1752
#endif
1753
    case TARGET_NR_access:
1754
        ret = get_errno(access((const char *)arg1, arg2));
1755
        break;
1756
    case TARGET_NR_nice:
1757
        ret = get_errno(nice(arg1));
1758
        break;
1759
#ifdef TARGET_NR_ftime
1760
    case TARGET_NR_ftime:
1761
        goto unimplemented;
1762
#endif
1763
    case TARGET_NR_sync:
1764
        sync();
1765
        ret = 0;
1766
        break;
1767
    case TARGET_NR_kill:
1768
        ret = get_errno(kill(arg1, arg2));
1769
        break;
1770
    case TARGET_NR_rename:
1771
        ret = get_errno(rename((const char *)arg1, (const char *)arg2));
1772
        break;
1773
    case TARGET_NR_mkdir:
1774
        ret = get_errno(mkdir((const char *)arg1, arg2));
1775
        break;
1776
    case TARGET_NR_rmdir:
1777
        ret = get_errno(rmdir((const char *)arg1));
1778
        break;
1779
    case TARGET_NR_dup:
1780
        ret = get_errno(dup(arg1));
1781
        break;
1782
    case TARGET_NR_pipe:
1783
        {
1784
            int *pipe_ptr = (int *)arg1;
1785
            ret = get_errno(pipe(pipe_ptr));
1786
            if (!is_error(ret)) {
1787
                tswap32s(&pipe_ptr[0]);
1788
                tswap32s(&pipe_ptr[1]);
1789
            }
1790
        }
1791
        break;
1792
    case TARGET_NR_times:
1793
        {
1794
            struct target_tms *tmsp = (void *)arg1;
1795
            struct tms tms;
1796
            ret = get_errno(times(&tms));
1797
            if (tmsp) {
1798
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
1799
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
1800
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
1801
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
1802
            }
1803
            if (!is_error(ret))
1804
                ret = host_to_target_clock_t(ret);
1805
        }
1806
        break;
1807
#ifdef TARGET_NR_prof
1808
    case TARGET_NR_prof:
1809
        goto unimplemented;
1810
#endif
1811
    case TARGET_NR_signal:
1812
        goto unimplemented;
1813

    
1814
    case TARGET_NR_acct:
1815
        goto unimplemented;
1816
    case TARGET_NR_umount2:
1817
        ret = get_errno(umount2((const char *)arg1, arg2));
1818
        break;
1819
#ifdef TARGET_NR_lock
1820
    case TARGET_NR_lock:
1821
        goto unimplemented;
1822
#endif
1823
    case TARGET_NR_ioctl:
1824
        ret = do_ioctl(arg1, arg2, arg3);
1825
        break;
1826
    case TARGET_NR_fcntl:
1827
        ret = get_errno(do_fcntl(arg1, arg2, arg3));
1828
        break;
1829
#ifdef TARGET_NR_mpx
1830
    case TARGET_NR_mpx:
1831
        goto unimplemented;
1832
#endif
1833
    case TARGET_NR_setpgid:
1834
        ret = get_errno(setpgid(arg1, arg2));
1835
        break;
1836
#ifdef TARGET_NR_ulimit
1837
    case TARGET_NR_ulimit:
1838
        goto unimplemented;
1839
#endif
1840
#ifdef TARGET_NR_oldolduname
1841
    case TARGET_NR_oldolduname:
1842
        goto unimplemented;
1843
#endif
1844
    case TARGET_NR_umask:
1845
        ret = get_errno(umask(arg1));
1846
        break;
1847
    case TARGET_NR_chroot:
1848
        ret = get_errno(chroot((const char *)arg1));
1849
        break;
1850
    case TARGET_NR_ustat:
1851
        goto unimplemented;
1852
    case TARGET_NR_dup2:
1853
        ret = get_errno(dup2(arg1, arg2));
1854
        break;
1855
    case TARGET_NR_getppid:
1856
        ret = get_errno(getppid());
1857
        break;
1858
    case TARGET_NR_getpgrp:
1859
        ret = get_errno(getpgrp());
1860
        break;
1861
    case TARGET_NR_setsid:
1862
        ret = get_errno(setsid());
1863
        break;
1864
    case TARGET_NR_sigaction:
1865
        {
1866
            struct target_old_sigaction *old_act = (void *)arg2;
1867
            struct target_old_sigaction *old_oact = (void *)arg3;
1868
            struct target_sigaction act, oact, *pact;
1869
            if (old_act) {
1870
                act._sa_handler = old_act->_sa_handler;
1871
                target_siginitset(&act.sa_mask, old_act->sa_mask);
1872
                act.sa_flags = old_act->sa_flags;
1873
                act.sa_restorer = old_act->sa_restorer;
1874
                pact = &act;
1875
            } else {
1876
                pact = NULL;
1877
            }
1878
            ret = get_errno(do_sigaction(arg1, pact, &oact));
1879
            if (!is_error(ret) && old_oact) {
1880
                old_oact->_sa_handler = oact._sa_handler;
1881
                old_oact->sa_mask = oact.sa_mask.sig[0];
1882
                old_oact->sa_flags = oact.sa_flags;
1883
                old_oact->sa_restorer = oact.sa_restorer;
1884
            }
1885
        }
1886
        break;
1887
    case TARGET_NR_rt_sigaction:
1888
        ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3));
1889
        break;
1890
    case TARGET_NR_sgetmask:
1891
        {
1892
            sigset_t cur_set;
1893
            target_ulong target_set;
1894
            sigprocmask(0, NULL, &cur_set);
1895
            host_to_target_old_sigset(&target_set, &cur_set);
1896
            ret = target_set;
1897
        }
1898
        break;
1899
    case TARGET_NR_ssetmask:
1900
        {
1901
            sigset_t set, oset, cur_set;
1902
            target_ulong target_set = arg1;
1903
            sigprocmask(0, NULL, &cur_set);
1904
            target_to_host_old_sigset(&set, &target_set);
1905
            sigorset(&set, &set, &cur_set);
1906
            sigprocmask(SIG_SETMASK, &set, &oset);
1907
            host_to_target_old_sigset(&target_set, &oset);
1908
            ret = target_set;
1909
        }
1910
        break;
1911
    case TARGET_NR_sigprocmask:
1912
        {
1913
            int how = arg1;
1914
            sigset_t set, oldset, *set_ptr;
1915
            target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
1916
            
1917
            if (pset) {
1918
                switch(how) {
1919
                case TARGET_SIG_BLOCK:
1920
                    how = SIG_BLOCK;
1921
                    break;
1922
                case TARGET_SIG_UNBLOCK:
1923
                    how = SIG_UNBLOCK;
1924
                    break;
1925
                case TARGET_SIG_SETMASK:
1926
                    how = SIG_SETMASK;
1927
                    break;
1928
                default:
1929
                    ret = -EINVAL;
1930
                    goto fail;
1931
                }
1932
                target_to_host_old_sigset(&set, pset);
1933
                set_ptr = &set;
1934
            } else {
1935
                how = 0;
1936
                set_ptr = NULL;
1937
            }
1938
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1939
            if (!is_error(ret) && poldset) {
1940
                host_to_target_old_sigset(poldset, &oldset);
1941
            }
1942
        }
1943
        break;
1944
    case TARGET_NR_rt_sigprocmask:
1945
        {
1946
            int how = arg1;
1947
            sigset_t set, oldset, *set_ptr;
1948
            target_sigset_t *pset = (void *)arg2;
1949
            target_sigset_t *poldset = (void *)arg3;
1950
            
1951
            if (pset) {
1952
                switch(how) {
1953
                case TARGET_SIG_BLOCK:
1954
                    how = SIG_BLOCK;
1955
                    break;
1956
                case TARGET_SIG_UNBLOCK:
1957
                    how = SIG_UNBLOCK;
1958
                    break;
1959
                case TARGET_SIG_SETMASK:
1960
                    how = SIG_SETMASK;
1961
                    break;
1962
                default:
1963
                    ret = -EINVAL;
1964
                    goto fail;
1965
                }
1966
                target_to_host_sigset(&set, pset);
1967
                set_ptr = &set;
1968
            } else {
1969
                how = 0;
1970
                set_ptr = NULL;
1971
            }
1972
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
1973
            if (!is_error(ret) && poldset) {
1974
                host_to_target_sigset(poldset, &oldset);
1975
            }
1976
        }
1977
        break;
1978
    case TARGET_NR_sigpending:
1979
        {
1980
            sigset_t set;
1981
            ret = get_errno(sigpending(&set));
1982
            if (!is_error(ret)) {
1983
                host_to_target_old_sigset((target_ulong *)arg1, &set);
1984
            }
1985
        }
1986
        break;
1987
    case TARGET_NR_rt_sigpending:
1988
        {
1989
            sigset_t set;
1990
            ret = get_errno(sigpending(&set));
1991
            if (!is_error(ret)) {
1992
                host_to_target_sigset((target_sigset_t *)arg1, &set);
1993
            }
1994
        }
1995
        break;
1996
    case TARGET_NR_sigsuspend:
1997
        {
1998
            sigset_t set;
1999
            target_to_host_old_sigset(&set, (target_ulong *)arg1);
2000
            ret = get_errno(sigsuspend(&set));
2001
        }
2002
        break;
2003
    case TARGET_NR_rt_sigsuspend:
2004
        {
2005
            sigset_t set;
2006
            target_to_host_sigset(&set, (target_sigset_t *)arg1);
2007
            ret = get_errno(sigsuspend(&set));
2008
        }
2009
        break;
2010
    case TARGET_NR_rt_sigtimedwait:
2011
        {
2012
            target_sigset_t *target_set = (void *)arg1;
2013
            target_siginfo_t *target_uinfo = (void *)arg2;
2014
            struct target_timespec *target_uts = (void *)arg3;
2015
            sigset_t set;
2016
            struct timespec uts, *puts;
2017
            siginfo_t uinfo;
2018
            
2019
            target_to_host_sigset(&set, target_set);
2020
            if (target_uts) {
2021
                puts = &uts;
2022
                puts->tv_sec = tswapl(target_uts->tv_sec);
2023
                puts->tv_nsec = tswapl(target_uts->tv_nsec);
2024
            } else {
2025
                puts = NULL;
2026
            }
2027
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
2028
            if (!is_error(ret) && target_uinfo) {
2029
                host_to_target_siginfo(target_uinfo, &uinfo);
2030
            }
2031
        }
2032
        break;
2033
    case TARGET_NR_rt_sigqueueinfo:
2034
        {
2035
            siginfo_t uinfo;
2036
            target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3);
2037
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
2038
        }
2039
        break;
2040
    case TARGET_NR_sigreturn:
2041
        /* NOTE: ret is eax, so not transcoding must be done */
2042
        ret = do_sigreturn(cpu_env);
2043
        break;
2044
    case TARGET_NR_rt_sigreturn:
2045
        /* NOTE: ret is eax, so not transcoding must be done */
2046
        ret = do_rt_sigreturn(cpu_env);
2047
        break;
2048
    case TARGET_NR_sethostname:
2049
        ret = get_errno(sethostname((const char *)arg1, arg2));
2050
        break;
2051
    case TARGET_NR_setrlimit:
2052
        {
2053
            /* XXX: convert resource ? */
2054
            int resource = arg1;
2055
            struct target_rlimit *target_rlim = (void *)arg2;
2056
            struct rlimit rlim;
2057
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
2058
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
2059
            ret = get_errno(setrlimit(resource, &rlim));
2060
        }
2061
        break;
2062
    case TARGET_NR_getrlimit:
2063
        {
2064
            /* XXX: convert resource ? */
2065
            int resource = arg1;
2066
            struct target_rlimit *target_rlim = (void *)arg2;
2067
            struct rlimit rlim;
2068
            
2069
            ret = get_errno(getrlimit(resource, &rlim));
2070
            if (!is_error(ret)) {
2071
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2072
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
2073
            }
2074
        }
2075
        break;
2076
    case TARGET_NR_getrusage:
2077
        {
2078
            struct rusage rusage;
2079
            struct target_rusage *target_rusage = (void *)arg2;
2080
            ret = get_errno(getrusage(arg1, &rusage));
2081
            if (!is_error(ret)) {
2082
                host_to_target_rusage(target_rusage, &rusage);
2083
            }
2084
        }
2085
        break;
2086
    case TARGET_NR_gettimeofday:
2087
        {
2088
            struct target_timeval *target_tv = (void *)arg1;
2089
            struct timeval tv;
2090
            ret = get_errno(gettimeofday(&tv, NULL));
2091
            if (!is_error(ret)) {
2092
                host_to_target_timeval(target_tv, &tv);
2093
            }
2094
        }
2095
        break;
2096
    case TARGET_NR_settimeofday:
2097
        {
2098
            struct target_timeval *target_tv = (void *)arg1;
2099
            struct timeval tv;
2100
            target_to_host_timeval(&tv, target_tv);
2101
            ret = get_errno(settimeofday(&tv, NULL));
2102
        }
2103
        break;
2104
    case TARGET_NR_select:
2105
        {
2106
            struct target_sel_arg_struct *sel = (void *)arg1;
2107
            sel->n = tswapl(sel->n);
2108
            sel->inp = tswapl(sel->inp);
2109
            sel->outp = tswapl(sel->outp);
2110
            sel->exp = tswapl(sel->exp);
2111
            sel->tvp = tswapl(sel->tvp);
2112
            ret = do_select(sel->n, (void *)sel->inp, (void *)sel->outp,
2113
                            (void *)sel->exp, (void *)sel->tvp);
2114
        }
2115
        break;
2116
    case TARGET_NR_symlink:
2117
        ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
2118
        break;
2119
#ifdef TARGET_NR_oldlstat
2120
    case TARGET_NR_oldlstat:
2121
        goto unimplemented;
2122
#endif
2123
    case TARGET_NR_readlink:
2124
        ret = get_errno(readlink(path((const char *)arg1), (char *)arg2, arg3));
2125
        break;
2126
    case TARGET_NR_uselib:
2127
        goto unimplemented;
2128
    case TARGET_NR_swapon:
2129
        ret = get_errno(swapon((const char *)arg1, arg2));
2130
        break;
2131
    case TARGET_NR_reboot:
2132
        goto unimplemented;
2133
    case TARGET_NR_readdir:
2134
        goto unimplemented;
2135
    case TARGET_NR_mmap:
2136
#if defined(TARGET_I386) || defined(TARGET_ARM)
2137
        {
2138
            uint32_t v1, v2, v3, v4, v5, v6, *vptr;
2139
            vptr = (uint32_t *)arg1;
2140
            v1 = tswap32(vptr[0]);
2141
            v2 = tswap32(vptr[1]);
2142
            v3 = tswap32(vptr[2]);
2143
            v4 = tswap32(vptr[3]);
2144
            v5 = tswap32(vptr[4]);
2145
            v6 = tswap32(vptr[5]);
2146
            ret = get_errno(target_mmap(v1, v2, v3, 
2147
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
2148
                                        v5, v6));
2149
        }
2150
#else
2151
        ret = get_errno(target_mmap(arg1, arg2, arg3, 
2152
                                    target_to_host_bitmask(arg4, mmap_flags_tbl), 
2153
                                    arg5,
2154
                                    arg6));
2155
#endif
2156
        break;
2157
    case TARGET_NR_mmap2:
2158
#if defined(TARGET_SPARC)
2159
#define MMAP_SHIFT 12
2160
#else
2161
#define MMAP_SHIFT TARGET_PAGE_BITS
2162
#endif
2163
        ret = get_errno(target_mmap(arg1, arg2, arg3, 
2164
                                    target_to_host_bitmask(arg4, mmap_flags_tbl), 
2165
                                    arg5,
2166
                                    arg6 << MMAP_SHIFT));
2167
        break;
2168
    case TARGET_NR_munmap:
2169
        ret = get_errno(target_munmap(arg1, arg2));
2170
        break;
2171
    case TARGET_NR_mprotect:
2172
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
2173
        break;
2174
    case TARGET_NR_mremap:
2175
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
2176
        break;
2177
    case TARGET_NR_msync:
2178
        ret = get_errno(msync((void *)arg1, arg2, arg3));
2179
        break;
2180
    case TARGET_NR_mlock:
2181
        ret = get_errno(mlock((void *)arg1, arg2));
2182
        break;
2183
    case TARGET_NR_munlock:
2184
        ret = get_errno(munlock((void *)arg1, arg2));
2185
        break;
2186
    case TARGET_NR_mlockall:
2187
        ret = get_errno(mlockall(arg1));
2188
        break;
2189
    case TARGET_NR_munlockall:
2190
        ret = get_errno(munlockall());
2191
        break;
2192
    case TARGET_NR_truncate:
2193
        ret = get_errno(truncate((const char *)arg1, arg2));
2194
        break;
2195
    case TARGET_NR_ftruncate:
2196
        ret = get_errno(ftruncate(arg1, arg2));
2197
        break;
2198
    case TARGET_NR_fchmod:
2199
        ret = get_errno(fchmod(arg1, arg2));
2200
        break;
2201
    case TARGET_NR_getpriority:
2202
        ret = get_errno(getpriority(arg1, arg2));
2203
        break;
2204
    case TARGET_NR_setpriority:
2205
        ret = get_errno(setpriority(arg1, arg2, arg3));
2206
        break;
2207
#ifdef TARGET_NR_profil
2208
    case TARGET_NR_profil:
2209
        goto unimplemented;
2210
#endif
2211
    case TARGET_NR_statfs:
2212
        stfs = (void *)arg2;
2213
        ret = get_errno(sys_statfs(path((const char *)arg1), stfs));
2214
    convert_statfs:
2215
        if (!is_error(ret)) {
2216
            tswap32s(&stfs->f_type);
2217
            tswap32s(&stfs->f_bsize);
2218
            tswap32s(&stfs->f_blocks);
2219
            tswap32s(&stfs->f_bfree);
2220
            tswap32s(&stfs->f_bavail);
2221
            tswap32s(&stfs->f_files);
2222
            tswap32s(&stfs->f_ffree);
2223
            tswap32s(&stfs->f_fsid.val[0]);
2224
            tswap32s(&stfs->f_fsid.val[1]);
2225
            tswap32s(&stfs->f_namelen);
2226
        }
2227
        break;
2228
    case TARGET_NR_fstatfs:
2229
        stfs = (void *)arg2;
2230
        ret = get_errno(sys_fstatfs(arg1, stfs));
2231
        goto convert_statfs;
2232
#ifdef TARGET_NR_ioperm
2233
    case TARGET_NR_ioperm:
2234
        goto unimplemented;
2235
#endif
2236
    case TARGET_NR_socketcall:
2237
        ret = do_socketcall(arg1, (int32_t *)arg2);
2238
        break;
2239
    case TARGET_NR_syslog:
2240
        goto unimplemented;
2241
    case TARGET_NR_setitimer:
2242
        {
2243
            struct target_itimerval *target_value = (void *)arg2;
2244
            struct target_itimerval *target_ovalue = (void *)arg3;
2245
            struct itimerval value, ovalue, *pvalue;
2246

    
2247
            if (target_value) {
2248
                pvalue = &value;
2249
                target_to_host_timeval(&pvalue->it_interval, 
2250
                                       &target_value->it_interval);
2251
                target_to_host_timeval(&pvalue->it_value, 
2252
                                       &target_value->it_value);
2253
            } else {
2254
                pvalue = NULL;
2255
            }
2256
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
2257
            if (!is_error(ret) && target_ovalue) {
2258
                host_to_target_timeval(&target_ovalue->it_interval, 
2259
                                       &ovalue.it_interval);
2260
                host_to_target_timeval(&target_ovalue->it_value, 
2261
                                       &ovalue.it_value);
2262
            }
2263
        }
2264
        break;
2265
    case TARGET_NR_getitimer:
2266
        {
2267
            struct target_itimerval *target_value = (void *)arg2;
2268
            struct itimerval value;
2269
            
2270
            ret = get_errno(getitimer(arg1, &value));
2271
            if (!is_error(ret) && target_value) {
2272
                host_to_target_timeval(&target_value->it_interval, 
2273
                                       &value.it_interval);
2274
                host_to_target_timeval(&target_value->it_value, 
2275
                                       &value.it_value);
2276
            }
2277
        }
2278
        break;
2279
    case TARGET_NR_stat:
2280
        ret = get_errno(stat(path((const char *)arg1), &st));
2281
        goto do_stat;
2282
    case TARGET_NR_lstat:
2283
        ret = get_errno(lstat(path((const char *)arg1), &st));
2284
        goto do_stat;
2285
    case TARGET_NR_fstat:
2286
        {
2287
            ret = get_errno(fstat(arg1, &st));
2288
        do_stat:
2289
            if (!is_error(ret)) {
2290
                struct target_stat *target_st = (void *)arg2;
2291
                target_st->st_dev = tswap16(st.st_dev);
2292
                target_st->st_ino = tswapl(st.st_ino);
2293
#if defined(TARGET_PPC)
2294
                target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
2295
                target_st->st_uid = tswap32(st.st_uid);
2296
                target_st->st_gid = tswap32(st.st_gid);
2297
#else
2298
                target_st->st_mode = tswap16(st.st_mode);
2299
                target_st->st_uid = tswap16(st.st_uid);
2300
                target_st->st_gid = tswap16(st.st_gid);
2301
#endif
2302
                target_st->st_nlink = tswap16(st.st_nlink);
2303
                target_st->st_rdev = tswap16(st.st_rdev);
2304
                target_st->st_size = tswapl(st.st_size);
2305
                target_st->st_blksize = tswapl(st.st_blksize);
2306
                target_st->st_blocks = tswapl(st.st_blocks);
2307
                target_st->target_st_atime = tswapl(st.st_atime);
2308
                target_st->target_st_mtime = tswapl(st.st_mtime);
2309
                target_st->target_st_ctime = tswapl(st.st_ctime);
2310
            }
2311
        }
2312
        break;
2313
#ifdef TARGET_NR_olduname
2314
    case TARGET_NR_olduname:
2315
        goto unimplemented;
2316
#endif
2317
#ifdef TARGET_NR_iopl
2318
    case TARGET_NR_iopl:
2319
        goto unimplemented;
2320
#endif
2321
    case TARGET_NR_vhangup:
2322
        ret = get_errno(vhangup());
2323
        break;
2324
#ifdef TARGET_NR_idle
2325
    case TARGET_NR_idle:
2326
        goto unimplemented;
2327
#endif
2328
    case TARGET_NR_wait4:
2329
        {
2330
            int status;
2331
            target_long *status_ptr = (void *)arg2;
2332
            struct rusage rusage, *rusage_ptr;
2333
            struct target_rusage *target_rusage = (void *)arg4;
2334
            if (target_rusage)
2335
                rusage_ptr = &rusage;
2336
            else
2337
                rusage_ptr = NULL;
2338
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
2339
            if (!is_error(ret)) {
2340
                if (status_ptr)
2341
                    *status_ptr = tswap32(status);
2342
                if (target_rusage) {
2343
                    host_to_target_rusage(target_rusage, &rusage);
2344
                }
2345
            }
2346
        }
2347
        break;
2348
    case TARGET_NR_swapoff:
2349
        ret = get_errno(swapoff((const char *)arg1));
2350
        break;
2351
    case TARGET_NR_sysinfo:
2352
        {
2353
            struct target_sysinfo *target_value = (void *)arg1;
2354
            struct sysinfo value;
2355
            ret = get_errno(sysinfo(&value));
2356
            if (!is_error(ret) && target_value)
2357
            {
2358
                __put_user(value.uptime, &target_value->uptime);
2359
                __put_user(value.loads[0], &target_value->loads[0]);
2360
                __put_user(value.loads[1], &target_value->loads[1]);
2361
                __put_user(value.loads[2], &target_value->loads[2]);
2362
                __put_user(value.totalram, &target_value->totalram);
2363
                __put_user(value.freeram, &target_value->freeram);
2364
                __put_user(value.sharedram, &target_value->sharedram);
2365
                __put_user(value.bufferram, &target_value->bufferram);
2366
                __put_user(value.totalswap, &target_value->totalswap);
2367
                __put_user(value.freeswap, &target_value->freeswap);
2368
                __put_user(value.procs, &target_value->procs);
2369
                __put_user(value.totalhigh, &target_value->totalhigh);
2370
                __put_user(value.freehigh, &target_value->freehigh);
2371
                __put_user(value.mem_unit, &target_value->mem_unit);
2372
            }
2373
        }
2374
        break;
2375
    case TARGET_NR_ipc:
2376
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
2377
        break;
2378
    case TARGET_NR_fsync:
2379
        ret = get_errno(fsync(arg1));
2380
        break;
2381
    case TARGET_NR_clone:
2382
        ret = get_errno(do_fork(cpu_env, arg1, arg2));
2383
        break;
2384
#ifdef __NR_exit_group
2385
        /* new thread calls */
2386
    case TARGET_NR_exit_group:
2387
        ret = get_errno(exit_group(arg1));
2388
        break;
2389
#endif
2390
    case TARGET_NR_setdomainname:
2391
        ret = get_errno(setdomainname((const char *)arg1, arg2));
2392
        break;
2393
    case TARGET_NR_uname:
2394
        /* no need to transcode because we use the linux syscall */
2395
        ret = get_errno(sys_uname((struct new_utsname *)arg1));
2396
        break;
2397
#ifdef TARGET_I386
2398
    case TARGET_NR_modify_ldt:
2399
        ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
2400
        break;
2401
    case TARGET_NR_vm86old:
2402
        goto unimplemented;
2403
    case TARGET_NR_vm86:
2404
        ret = do_vm86(cpu_env, arg1, (void *)arg2);
2405
        break;
2406
#endif
2407
    case TARGET_NR_adjtimex:
2408
        goto unimplemented;
2409
    case TARGET_NR_create_module:
2410
    case TARGET_NR_init_module:
2411
    case TARGET_NR_delete_module:
2412
    case TARGET_NR_get_kernel_syms:
2413
        goto unimplemented;
2414
    case TARGET_NR_quotactl:
2415
        goto unimplemented;
2416
    case TARGET_NR_getpgid:
2417
        ret = get_errno(getpgid(arg1));
2418
        break;
2419
    case TARGET_NR_fchdir:
2420
        ret = get_errno(fchdir(arg1));
2421
        break;
2422
    case TARGET_NR_bdflush:
2423
        goto unimplemented;
2424
    case TARGET_NR_sysfs:
2425
        goto unimplemented;
2426
    case TARGET_NR_personality:
2427
        ret = get_errno(personality(arg1));
2428
        break;
2429
    case TARGET_NR_afs_syscall:
2430
        goto unimplemented;
2431
    case TARGET_NR__llseek:
2432
        {
2433
#if defined (__x86_64__)
2434
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
2435
            *(int64_t *)arg4 = ret;
2436
#else
2437
            int64_t res;
2438
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
2439
            *(int64_t *)arg4 = tswap64(res);
2440
#endif
2441
        }
2442
        break;
2443
    case TARGET_NR_getdents:
2444
#if TARGET_LONG_SIZE != 4
2445
#error not supported
2446
#elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
2447
        {
2448
            struct target_dirent *target_dirp = (void *)arg2;
2449
            struct dirent *dirp;
2450
            long count = arg3;
2451

    
2452
            dirp = malloc(count);
2453
            if (!dirp)
2454
                return -ENOMEM;
2455
            
2456
            ret = get_errno(sys_getdents(arg1, dirp, count));
2457
            if (!is_error(ret)) {
2458
                struct dirent *de;
2459
                struct target_dirent *tde;
2460
                int len = ret;
2461
                int reclen, treclen;
2462
                int count1, tnamelen;
2463

    
2464
                count1 = 0;
2465
                de = dirp;
2466
                tde = target_dirp;
2467
                while (len > 0) {
2468
                    reclen = de->d_reclen;
2469
                    treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
2470
                    tde->d_reclen = tswap16(treclen);
2471
                    tde->d_ino = tswapl(de->d_ino);
2472
                    tde->d_off = tswapl(de->d_off);
2473
                    tnamelen = treclen - (2 * sizeof(target_long) + 2);
2474
                    if (tnamelen > 256)
2475
                        tnamelen = 256;
2476
                    strncpy(tde->d_name, de->d_name, tnamelen);
2477
                    de = (struct dirent *)((char *)de + reclen);
2478
                    len -= reclen;
2479
                    tde = (struct dirent *)((char *)tde + treclen);
2480
                    count1 += treclen;
2481
                }
2482
                ret = count1;
2483
            }
2484
            free(dirp);
2485
        }
2486
#else
2487
        {
2488
            struct dirent *dirp = (void *)arg2;
2489
            long count = arg3;
2490

    
2491
            ret = get_errno(sys_getdents(arg1, dirp, count));
2492
            if (!is_error(ret)) {
2493
                struct dirent *de;
2494
                int len = ret;
2495
                int reclen;
2496
                de = dirp;
2497
                while (len > 0) {
2498
                    reclen = de->d_reclen;
2499
                    if (reclen > len)
2500
                        break;
2501
                    de->d_reclen = tswap16(reclen);
2502
                    tswapls(&de->d_ino);
2503
                    tswapls(&de->d_off);
2504
                    de = (struct dirent *)((char *)de + reclen);
2505
                    len -= reclen;
2506
                }
2507
            }
2508
        }
2509
#endif
2510
        break;
2511
#ifdef TARGET_NR_getdents64
2512
    case TARGET_NR_getdents64:
2513
        {
2514
            struct dirent64 *dirp = (void *)arg2;
2515
            long count = arg3;
2516
            ret = get_errno(sys_getdents64(arg1, dirp, count));
2517
            if (!is_error(ret)) {
2518
                struct dirent64 *de;
2519
                int len = ret;
2520
                int reclen;
2521
                de = dirp;
2522
                while (len > 0) {
2523
                    reclen = de->d_reclen;
2524
                    if (reclen > len)
2525
                        break;
2526
                    de->d_reclen = tswap16(reclen);
2527
                    tswap64s(&de->d_ino);
2528
                    tswap64s(&de->d_off);
2529
                    de = (struct dirent64 *)((char *)de + reclen);
2530
                    len -= reclen;
2531
                }
2532
            }
2533
        }
2534
        break;
2535
#endif /* TARGET_NR_getdents64 */
2536
    case TARGET_NR__newselect:
2537
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
2538
                        (void *)arg5);
2539
        break;
2540
    case TARGET_NR_poll:
2541
        {
2542
            struct target_pollfd *target_pfd = (void *)arg1;
2543
            unsigned int nfds = arg2;
2544
            int timeout = arg3;
2545
            struct pollfd *pfd;
2546
            unsigned int i;
2547

    
2548
            pfd = alloca(sizeof(struct pollfd) * nfds);
2549
            for(i = 0; i < nfds; i++) {
2550
                pfd[i].fd = tswap32(target_pfd[i].fd);
2551
                pfd[i].events = tswap16(target_pfd[i].events);
2552
            }
2553
            ret = get_errno(poll(pfd, nfds, timeout));
2554
            if (!is_error(ret)) {
2555
                for(i = 0; i < nfds; i++) {
2556
                    target_pfd[i].revents = tswap16(pfd[i].revents);
2557
                }
2558
            }
2559
        }
2560
        break;
2561
    case TARGET_NR_flock:
2562
        /* NOTE: the flock constant seems to be the same for every
2563
           Linux platform */
2564
        ret = get_errno(flock(arg1, arg2));
2565
        break;
2566
    case TARGET_NR_readv:
2567
        {
2568
            int count = arg3;
2569
            int i;
2570
            struct iovec *vec;
2571
            struct target_iovec *target_vec = (void *)arg2;
2572

    
2573
            vec = alloca(count * sizeof(struct iovec));
2574
            for(i = 0;i < count; i++) {
2575
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2576
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
2577
            }
2578
            ret = get_errno(readv(arg1, vec, count));
2579
        }
2580
        break;
2581
    case TARGET_NR_writev:
2582
        {
2583
            int count = arg3;
2584
            int i;
2585
            struct iovec *vec;
2586
            struct target_iovec *target_vec = (void *)arg2;
2587

    
2588
            vec = alloca(count * sizeof(struct iovec));
2589
            for(i = 0;i < count; i++) {
2590
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2591
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
2592
            }
2593
            ret = get_errno(writev(arg1, vec, count));
2594
        }
2595
        break;
2596
    case TARGET_NR_getsid:
2597
        ret = get_errno(getsid(arg1));
2598
        break;
2599
    case TARGET_NR_fdatasync:
2600
        ret = get_errno(fdatasync(arg1));
2601
        break;
2602
    case TARGET_NR__sysctl:
2603
        goto unimplemented;
2604
    case TARGET_NR_sched_setparam:
2605
        {
2606
            struct sched_param *target_schp = (void *)arg2;
2607
            struct sched_param schp;
2608
            schp.sched_priority = tswap32(target_schp->sched_priority);
2609
            ret = get_errno(sched_setparam(arg1, &schp));
2610
        }
2611
        break;
2612
    case TARGET_NR_sched_getparam:
2613
        {
2614
            struct sched_param *target_schp = (void *)arg2;
2615
            struct sched_param schp;
2616
            ret = get_errno(sched_getparam(arg1, &schp));
2617
            if (!is_error(ret)) {
2618
                target_schp->sched_priority = tswap32(schp.sched_priority);
2619
            }
2620
        }
2621
        break;
2622
    case TARGET_NR_sched_setscheduler:
2623
        {
2624
            struct sched_param *target_schp = (void *)arg3;
2625
            struct sched_param schp;
2626
            schp.sched_priority = tswap32(target_schp->sched_priority);
2627
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
2628
        }
2629
        break;
2630
    case TARGET_NR_sched_getscheduler:
2631
        ret = get_errno(sched_getscheduler(arg1));
2632
        break;
2633
    case TARGET_NR_sched_yield:
2634
        ret = get_errno(sched_yield());
2635
        break;
2636
    case TARGET_NR_sched_get_priority_max:
2637
        ret = get_errno(sched_get_priority_max(arg1));
2638
        break;
2639
    case TARGET_NR_sched_get_priority_min:
2640
        ret = get_errno(sched_get_priority_min(arg1));
2641
        break;
2642
    case TARGET_NR_sched_rr_get_interval:
2643
        {
2644
            struct target_timespec *target_ts = (void *)arg2;
2645
            struct timespec ts;
2646
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
2647
            if (!is_error(ret)) {
2648
                target_ts->tv_sec = tswapl(ts.tv_sec);
2649
                target_ts->tv_nsec = tswapl(ts.tv_nsec);
2650
            }
2651
        }
2652
        break;
2653
    case TARGET_NR_nanosleep:
2654
        {
2655
            struct target_timespec *target_req = (void *)arg1;
2656
            struct target_timespec *target_rem = (void *)arg2;
2657
            struct timespec req, rem;
2658
            req.tv_sec = tswapl(target_req->tv_sec);
2659
            req.tv_nsec = tswapl(target_req->tv_nsec);
2660
            ret = get_errno(nanosleep(&req, &rem));
2661
            if (is_error(ret) && target_rem) {
2662
                target_rem->tv_sec = tswapl(rem.tv_sec);
2663
                target_rem->tv_nsec = tswapl(rem.tv_nsec);
2664
            }
2665
        }
2666
        break;
2667
    case TARGET_NR_query_module:
2668
        goto unimplemented;
2669
    case TARGET_NR_nfsservctl:
2670
        goto unimplemented;
2671
    case TARGET_NR_prctl:
2672
        goto unimplemented;
2673
#ifdef TARGET_NR_pread
2674
    case TARGET_NR_pread:
2675
        page_unprotect_range((void *)arg2, arg3);
2676
        ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4));
2677
        break;
2678
    case TARGET_NR_pwrite:
2679
        ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
2680
        break;
2681
#endif
2682
    case TARGET_NR_getcwd:
2683
        ret = get_errno(sys_getcwd1((char *)arg1, arg2));
2684
        break;
2685
    case TARGET_NR_capget:
2686
        goto unimplemented;
2687
    case TARGET_NR_capset:
2688
        goto unimplemented;
2689
    case TARGET_NR_sigaltstack:
2690
        goto unimplemented;
2691
    case TARGET_NR_sendfile:
2692
        goto unimplemented;
2693
#ifdef TARGET_NR_getpmsg
2694
    case TARGET_NR_getpmsg:
2695
        goto unimplemented;
2696
#endif
2697
#ifdef TARGET_NR_putpmsg
2698
    case TARGET_NR_putpmsg:
2699
        goto unimplemented;
2700
#endif
2701
    case TARGET_NR_vfork:
2702
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
2703
        break;
2704
#ifdef TARGET_NR_ugetrlimit
2705
    case TARGET_NR_ugetrlimit:
2706
    {
2707
        struct rlimit rlim;
2708
        ret = get_errno(getrlimit(arg1, &rlim));
2709
        if (!is_error(ret)) {
2710
            struct target_rlimit *target_rlim = (void *)arg2;
2711
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2712
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
2713
        }
2714
        break;
2715
    }
2716
#endif
2717
    case TARGET_NR_truncate64:
2718
        goto unimplemented;
2719
    case TARGET_NR_ftruncate64:
2720
        goto unimplemented;
2721
    case TARGET_NR_stat64:
2722
        ret = get_errno(stat(path((const char *)arg1), &st));
2723
        goto do_stat64;
2724
    case TARGET_NR_lstat64:
2725
        ret = get_errno(lstat(path((const char *)arg1), &st));
2726
        goto do_stat64;
2727
    case TARGET_NR_fstat64:
2728
        {
2729
            ret = get_errno(fstat(arg1, &st));
2730
        do_stat64:
2731
            if (!is_error(ret)) {
2732
                struct target_stat64 *target_st = (void *)arg2;
2733
                memset(target_st, 0, sizeof(struct target_stat64));
2734
                put_user(st.st_dev, &target_st->st_dev);
2735
                put_user(st.st_ino, &target_st->st_ino);
2736
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
2737
                put_user(st.st_ino, &target_st->__st_ino);
2738
#endif
2739
                put_user(st.st_mode, &target_st->st_mode);
2740
                put_user(st.st_nlink, &target_st->st_nlink);
2741
                put_user(st.st_uid, &target_st->st_uid);
2742
                put_user(st.st_gid, &target_st->st_gid);
2743
                put_user(st.st_rdev, &target_st->st_rdev);
2744
                /* XXX: better use of kernel struct */
2745
                put_user(st.st_size, &target_st->st_size);
2746
                put_user(st.st_blksize, &target_st->st_blksize);
2747
                put_user(st.st_blocks, &target_st->st_blocks);
2748
                put_user(st.st_atime, &target_st->target_st_atime);
2749
                put_user(st.st_mtime, &target_st->target_st_mtime);
2750
                put_user(st.st_ctime, &target_st->target_st_ctime);
2751
            }
2752
        }
2753
        break;
2754

    
2755
#ifdef USE_UID16
2756
    case TARGET_NR_lchown:
2757
        ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2758
        break;
2759
    case TARGET_NR_getuid:
2760
        ret = get_errno(high2lowuid(getuid()));
2761
        break;
2762
    case TARGET_NR_getgid:
2763
        ret = get_errno(high2lowgid(getgid()));
2764
        break;
2765
    case TARGET_NR_geteuid:
2766
        ret = get_errno(high2lowuid(geteuid()));
2767
        break;
2768
    case TARGET_NR_getegid:
2769
        ret = get_errno(high2lowgid(getegid()));
2770
        break;
2771
    case TARGET_NR_setreuid:
2772
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
2773
        break;
2774
    case TARGET_NR_setregid:
2775
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
2776
        break;
2777
    case TARGET_NR_getgroups:
2778
        {
2779
            int gidsetsize = arg1;
2780
            uint16_t *target_grouplist = (void *)arg2;
2781
            gid_t *grouplist;
2782
            int i;
2783

    
2784
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2785
            ret = get_errno(getgroups(gidsetsize, grouplist));
2786
            if (!is_error(ret)) {
2787
                for(i = 0;i < gidsetsize; i++)
2788
                    target_grouplist[i] = tswap16(grouplist[i]);
2789
            }
2790
        }
2791
        break;
2792
    case TARGET_NR_setgroups:
2793
        {
2794
            int gidsetsize = arg1;
2795
            uint16_t *target_grouplist = (void *)arg2;
2796
            gid_t *grouplist;
2797
            int i;
2798

    
2799
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2800
            for(i = 0;i < gidsetsize; i++)
2801
                grouplist[i] = tswap16(target_grouplist[i]);
2802
            ret = get_errno(setgroups(gidsetsize, grouplist));
2803
        }
2804
        break;
2805
    case TARGET_NR_fchown:
2806
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
2807
        break;
2808
#ifdef TARGET_NR_setresuid
2809
    case TARGET_NR_setresuid:
2810
        ret = get_errno(setresuid(low2highuid(arg1), 
2811
                                  low2highuid(arg2), 
2812
                                  low2highuid(arg3)));
2813
        break;
2814
#endif
2815
#ifdef TARGET_NR_getresuid
2816
    case TARGET_NR_getresuid:
2817
        {
2818
            int ruid, euid, suid;
2819
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2820
            if (!is_error(ret)) {
2821
                *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
2822
                *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
2823
                *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
2824
            }
2825
        }
2826
        break;
2827
#endif
2828
#ifdef TARGET_NR_getresgid
2829
    case TARGET_NR_setresgid:
2830
        ret = get_errno(setresgid(low2highgid(arg1), 
2831
                                  low2highgid(arg2), 
2832
                                  low2highgid(arg3)));
2833
        break;
2834
#endif
2835
#ifdef TARGET_NR_getresgid
2836
    case TARGET_NR_getresgid:
2837
        {
2838
            int rgid, egid, sgid;
2839
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
2840
            if (!is_error(ret)) {
2841
                *(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
2842
                *(uint16_t *)arg2 = tswap16(high2lowgid(egid));
2843
                *(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
2844
            }
2845
        }
2846
        break;
2847
#endif
2848
    case TARGET_NR_chown:
2849
        ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2850
        break;
2851
    case TARGET_NR_setuid:
2852
        ret = get_errno(setuid(low2highuid(arg1)));
2853
        break;
2854
    case TARGET_NR_setgid:
2855
        ret = get_errno(setgid(low2highgid(arg1)));
2856
        break;
2857
    case TARGET_NR_setfsuid:
2858
        ret = get_errno(setfsuid(arg1));
2859
        break;
2860
    case TARGET_NR_setfsgid:
2861
        ret = get_errno(setfsgid(arg1));
2862
        break;
2863
#endif /* USE_UID16 */
2864

    
2865
    case TARGET_NR_lchown32:
2866
        ret = get_errno(lchown((const char *)arg1, arg2, arg3));
2867
        break;
2868
    case TARGET_NR_getuid32:
2869
        ret = get_errno(getuid());
2870
        break;
2871
    case TARGET_NR_getgid32:
2872
        ret = get_errno(getgid());
2873
        break;
2874
    case TARGET_NR_geteuid32:
2875
        ret = get_errno(geteuid());
2876
        break;
2877
    case TARGET_NR_getegid32:
2878
        ret = get_errno(getegid());
2879
        break;
2880
    case TARGET_NR_setreuid32:
2881
        ret = get_errno(setreuid(arg1, arg2));
2882
        break;
2883
    case TARGET_NR_setregid32:
2884
        ret = get_errno(setregid(arg1, arg2));
2885
        break;
2886
    case TARGET_NR_getgroups32:
2887
        goto unimplemented;
2888
    case TARGET_NR_setgroups32:
2889
        goto unimplemented;
2890
    case TARGET_NR_fchown32:
2891
        ret = get_errno(fchown(arg1, arg2, arg3));
2892
        break;
2893
    case TARGET_NR_setresuid32:
2894
        ret = get_errno(setresuid(arg1, arg2, arg3));
2895
        break;
2896
    case TARGET_NR_getresuid32:
2897
        {
2898
            int ruid, euid, suid;
2899
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2900
            if (!is_error(ret)) {
2901
                *(uint32_t *)arg1 = tswap32(ruid);
2902
                *(uint32_t *)arg2 = tswap32(euid);
2903
                *(uint32_t *)arg3 = tswap32(suid);
2904
            }
2905
        }
2906
        break;
2907
    case TARGET_NR_setresgid32:
2908
        ret = get_errno(setresgid(arg1, arg2, arg3));
2909
        break;
2910
    case TARGET_NR_getresgid32:
2911
        {
2912
            int rgid, egid, sgid;
2913
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
2914
            if (!is_error(ret)) {
2915
                *(uint32_t *)arg1 = tswap32(rgid);
2916
                *(uint32_t *)arg2 = tswap32(egid);
2917
                *(uint32_t *)arg3 = tswap32(sgid);
2918
            }
2919
        }
2920
        break;
2921
    case TARGET_NR_chown32:
2922
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
2923
        break;
2924
    case TARGET_NR_setuid32:
2925
        ret = get_errno(setuid(arg1));
2926
        break;
2927
    case TARGET_NR_setgid32:
2928
        ret = get_errno(setgid(arg1));
2929
        break;
2930
    case TARGET_NR_setfsuid32:
2931
        ret = get_errno(setfsuid(arg1));
2932
        break;
2933
    case TARGET_NR_setfsgid32:
2934
        ret = get_errno(setfsgid(arg1));
2935
        break;
2936

    
2937
    case TARGET_NR_pivot_root:
2938
        goto unimplemented;
2939
#ifdef TARGET_NR_mincore
2940
    case TARGET_NR_mincore:
2941
        goto unimplemented;
2942
#endif
2943
#ifdef TARGET_NR_madvise
2944
    case TARGET_NR_madvise:
2945
        goto unimplemented;
2946
#endif
2947
#if TARGET_LONG_BITS == 32
2948
    case TARGET_NR_fcntl64:
2949
    {
2950
        struct flock64 fl;
2951
        struct target_flock64 *target_fl = (void *)arg3;
2952

    
2953
        switch(arg2) {
2954
        case F_GETLK64:
2955
            ret = get_errno(fcntl(arg1, arg2, &fl));
2956
            if (ret == 0) {
2957
                target_fl->l_type = tswap16(fl.l_type);
2958
                target_fl->l_whence = tswap16(fl.l_whence);
2959
                target_fl->l_start = tswap64(fl.l_start);
2960
                target_fl->l_len = tswap64(fl.l_len);
2961
                target_fl->l_pid = tswapl(fl.l_pid);
2962
            }
2963
            break;
2964

    
2965
        case F_SETLK64:
2966
        case F_SETLKW64:
2967
            fl.l_type = tswap16(target_fl->l_type);
2968
            fl.l_whence = tswap16(target_fl->l_whence);
2969
            fl.l_start = tswap64(target_fl->l_start);
2970
            fl.l_len = tswap64(target_fl->l_len);
2971
            fl.l_pid = tswapl(target_fl->l_pid);
2972
            ret = get_errno(fcntl(arg1, arg2, &fl));
2973
            break;
2974
        default:
2975
            ret = get_errno(do_fcntl(arg1, arg2, arg3));
2976
            break;
2977
        }
2978
        break;
2979
    }
2980
#endif
2981
#ifdef TARGET_NR_security
2982
    case TARGET_NR_security:
2983
        goto unimplemented;
2984
#endif
2985
#ifdef TARGET_NR_getpagesize
2986
    case TARGET_NR_getpagesize:
2987
        ret = TARGET_PAGE_SIZE;
2988
        break;
2989
#endif
2990
    case TARGET_NR_gettid:
2991
        ret = get_errno(gettid());
2992
        break;
2993
    case TARGET_NR_readahead:
2994
        goto unimplemented;
2995
#ifdef TARGET_NR_setxattr
2996
    case TARGET_NR_setxattr:
2997
    case TARGET_NR_lsetxattr:
2998
    case TARGET_NR_fsetxattr:
2999
    case TARGET_NR_getxattr:
3000
    case TARGET_NR_lgetxattr:
3001
    case TARGET_NR_fgetxattr:
3002
    case TARGET_NR_listxattr:
3003
    case TARGET_NR_llistxattr:
3004
    case TARGET_NR_flistxattr:
3005
    case TARGET_NR_removexattr:
3006
    case TARGET_NR_lremovexattr:
3007
    case TARGET_NR_fremovexattr:
3008
        goto unimplemented_nowarn;
3009
#endif
3010
#ifdef TARGET_NR_set_thread_area
3011
    case TARGET_NR_set_thread_area:
3012
    case TARGET_NR_get_thread_area:
3013
        goto unimplemented_nowarn;
3014
#endif
3015
    default:
3016
    unimplemented:
3017
        gemu_log("qemu: Unsupported syscall: %d\n", num);
3018
    unimplemented_nowarn:
3019
        ret = -ENOSYS;
3020
        break;
3021
    }
3022
 fail:
3023
#ifdef DEBUG
3024
    gemu_log(" = %ld\n", ret);
3025
#endif
3026
    return ret;
3027
}
3028