Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 5e83e8e3

History | View | Annotate | Download (97.6 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
#ifdef SO_BSDCOMPAT
581
        case SO_BSDCOMPAT:
582
#endif
583
        case SO_PASSCRED:
584
        case SO_TIMESTAMP:
585
        case SO_RCVLOWAT:
586
        case SO_RCVTIMEO:
587
        case SO_SNDTIMEO:
588
            if (optlen < sizeof(uint32_t))
589
                return -EINVAL;
590
            if (get_user(val, (uint32_t *)optval))
591
                return -EFAULT;
592
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
593
            break;
594
        default:
595
            goto unimplemented;
596
        }
597
        break;
598
    default:
599
    unimplemented:
600
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
601
        ret = -ENOSYS;
602
    }
603
    return ret;
604
}
605

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
883

    
884
#define N_SHM_REGIONS        32
885

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

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

    
900
    version = call >> 16;
901
    call &= 0xffff;
902

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

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

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

    
969
/* kernel structure types definitions */
970
#define IFNAMSIZ        16
971

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

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

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

    
994
#define IOC_R 0x0001
995
#define IOC_W 0x0002
996
#define IOC_RW (IOC_R | IOC_W)
997

    
998
#define MAX_STRUCT_SIZE 4096
999

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

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

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

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

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

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

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

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

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

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

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

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

    
1275
#if defined(TARGET_I386)
1276

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

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

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

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

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

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

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

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

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

    
1392
#endif /* defined(TARGET_I386) */
1393

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

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

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

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

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

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

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

    
1514
#ifdef USE_UID16
1515

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

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

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

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

    
1548
#endif /* USE_UID16 */
1549

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

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

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

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

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

    
1662
            argp = alloca((argc + 1) * sizeof(void *));
1663
            envp = alloca((envc + 1) * sizeof(void *));
1664

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

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

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

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

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

    
2487
            dirp = malloc(count);
2488
            if (!dirp)
2489
                return -ENOMEM;
2490
            
2491
            ret = get_errno(sys_getdents(arg1, dirp, count));
2492
            if (!is_error(ret)) {
2493
                struct dirent *de;
2494
                struct target_dirent *tde;
2495
                int len = ret;
2496
                int reclen, treclen;
2497
                int count1, tnamelen;
2498

    
2499
                count1 = 0;
2500
                de = dirp;
2501
                tde = target_dirp;
2502
                while (len > 0) {
2503
                    reclen = de->d_reclen;
2504
                    treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
2505
                    tde->d_reclen = tswap16(treclen);
2506
                    tde->d_ino = tswapl(de->d_ino);
2507
                    tde->d_off = tswapl(de->d_off);
2508
                    tnamelen = treclen - (2 * sizeof(target_long) + 2);
2509
                    if (tnamelen > 256)
2510
                        tnamelen = 256;
2511
                    /* XXX: may not be correct */
2512
                    strncpy(tde->d_name, de->d_name, tnamelen);
2513
                    de = (struct dirent *)((char *)de + reclen);
2514
                    len -= reclen;
2515
                    tde = (struct dirent *)((char *)tde + treclen);
2516
                    count1 += treclen;
2517
                }
2518
                ret = count1;
2519
            }
2520
            free(dirp);
2521
        }
2522
#else
2523
        {
2524
            struct dirent *dirp = (void *)arg2;
2525
            long count = arg3;
2526

    
2527
            ret = get_errno(sys_getdents(arg1, dirp, count));
2528
            if (!is_error(ret)) {
2529
                struct dirent *de;
2530
                int len = ret;
2531
                int reclen;
2532
                de = dirp;
2533
                while (len > 0) {
2534
                    reclen = de->d_reclen;
2535
                    if (reclen > len)
2536
                        break;
2537
                    de->d_reclen = tswap16(reclen);
2538
                    tswapls(&de->d_ino);
2539
                    tswapls(&de->d_off);
2540
                    de = (struct dirent *)((char *)de + reclen);
2541
                    len -= reclen;
2542
                }
2543
            }
2544
        }
2545
#endif
2546
        break;
2547
#ifdef TARGET_NR_getdents64
2548
    case TARGET_NR_getdents64:
2549
        {
2550
            struct dirent64 *dirp = (void *)arg2;
2551
            long count = arg3;
2552
            ret = get_errno(sys_getdents64(arg1, dirp, count));
2553
            if (!is_error(ret)) {
2554
                struct dirent64 *de;
2555
                int len = ret;
2556
                int reclen;
2557
                de = dirp;
2558
                while (len > 0) {
2559
                    reclen = de->d_reclen;
2560
                    if (reclen > len)
2561
                        break;
2562
                    de->d_reclen = tswap16(reclen);
2563
                    tswap64s(&de->d_ino);
2564
                    tswap64s(&de->d_off);
2565
                    de = (struct dirent64 *)((char *)de + reclen);
2566
                    len -= reclen;
2567
                }
2568
            }
2569
        }
2570
        break;
2571
#endif /* TARGET_NR_getdents64 */
2572
    case TARGET_NR__newselect:
2573
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
2574
                        (void *)arg5);
2575
        break;
2576
    case TARGET_NR_poll:
2577
        {
2578
            struct target_pollfd *target_pfd = (void *)arg1;
2579
            unsigned int nfds = arg2;
2580
            int timeout = arg3;
2581
            struct pollfd *pfd;
2582
            unsigned int i;
2583

    
2584
            pfd = alloca(sizeof(struct pollfd) * nfds);
2585
            for(i = 0; i < nfds; i++) {
2586
                pfd[i].fd = tswap32(target_pfd[i].fd);
2587
                pfd[i].events = tswap16(target_pfd[i].events);
2588
            }
2589
            ret = get_errno(poll(pfd, nfds, timeout));
2590
            if (!is_error(ret)) {
2591
                for(i = 0; i < nfds; i++) {
2592
                    target_pfd[i].revents = tswap16(pfd[i].revents);
2593
                }
2594
            }
2595
        }
2596
        break;
2597
    case TARGET_NR_flock:
2598
        /* NOTE: the flock constant seems to be the same for every
2599
           Linux platform */
2600
        ret = get_errno(flock(arg1, arg2));
2601
        break;
2602
    case TARGET_NR_readv:
2603
        {
2604
            int count = arg3;
2605
            int i;
2606
            struct iovec *vec;
2607
            struct target_iovec *target_vec = (void *)arg2;
2608

    
2609
            vec = alloca(count * sizeof(struct iovec));
2610
            for(i = 0;i < count; i++) {
2611
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2612
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
2613
            }
2614
            ret = get_errno(readv(arg1, vec, count));
2615
        }
2616
        break;
2617
    case TARGET_NR_writev:
2618
        {
2619
            int count = arg3;
2620
            int i;
2621
            struct iovec *vec;
2622
            struct target_iovec *target_vec = (void *)arg2;
2623

    
2624
            vec = alloca(count * sizeof(struct iovec));
2625
            for(i = 0;i < count; i++) {
2626
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2627
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
2628
            }
2629
            ret = get_errno(writev(arg1, vec, count));
2630
        }
2631
        break;
2632
    case TARGET_NR_getsid:
2633
        ret = get_errno(getsid(arg1));
2634
        break;
2635
    case TARGET_NR_fdatasync:
2636
        ret = get_errno(fdatasync(arg1));
2637
        break;
2638
    case TARGET_NR__sysctl:
2639
        /* We don't implement this, but ENODIR is always a safe
2640
           return value. */
2641
        return -ENOTDIR;
2642
    case TARGET_NR_sched_setparam:
2643
        {
2644
            struct sched_param *target_schp = (void *)arg2;
2645
            struct sched_param schp;
2646
            schp.sched_priority = tswap32(target_schp->sched_priority);
2647
            ret = get_errno(sched_setparam(arg1, &schp));
2648
        }
2649
        break;
2650
    case TARGET_NR_sched_getparam:
2651
        {
2652
            struct sched_param *target_schp = (void *)arg2;
2653
            struct sched_param schp;
2654
            ret = get_errno(sched_getparam(arg1, &schp));
2655
            if (!is_error(ret)) {
2656
                target_schp->sched_priority = tswap32(schp.sched_priority);
2657
            }
2658
        }
2659
        break;
2660
    case TARGET_NR_sched_setscheduler:
2661
        {
2662
            struct sched_param *target_schp = (void *)arg3;
2663
            struct sched_param schp;
2664
            schp.sched_priority = tswap32(target_schp->sched_priority);
2665
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
2666
        }
2667
        break;
2668
    case TARGET_NR_sched_getscheduler:
2669
        ret = get_errno(sched_getscheduler(arg1));
2670
        break;
2671
    case TARGET_NR_sched_yield:
2672
        ret = get_errno(sched_yield());
2673
        break;
2674
    case TARGET_NR_sched_get_priority_max:
2675
        ret = get_errno(sched_get_priority_max(arg1));
2676
        break;
2677
    case TARGET_NR_sched_get_priority_min:
2678
        ret = get_errno(sched_get_priority_min(arg1));
2679
        break;
2680
    case TARGET_NR_sched_rr_get_interval:
2681
        {
2682
            struct target_timespec *target_ts = (void *)arg2;
2683
            struct timespec ts;
2684
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
2685
            if (!is_error(ret)) {
2686
                target_ts->tv_sec = tswapl(ts.tv_sec);
2687
                target_ts->tv_nsec = tswapl(ts.tv_nsec);
2688
            }
2689
        }
2690
        break;
2691
    case TARGET_NR_nanosleep:
2692
        {
2693
            struct target_timespec *target_req = (void *)arg1;
2694
            struct target_timespec *target_rem = (void *)arg2;
2695
            struct timespec req, rem;
2696
            req.tv_sec = tswapl(target_req->tv_sec);
2697
            req.tv_nsec = tswapl(target_req->tv_nsec);
2698
            ret = get_errno(nanosleep(&req, &rem));
2699
            if (is_error(ret) && target_rem) {
2700
                target_rem->tv_sec = tswapl(rem.tv_sec);
2701
                target_rem->tv_nsec = tswapl(rem.tv_nsec);
2702
            }
2703
        }
2704
        break;
2705
    case TARGET_NR_query_module:
2706
        goto unimplemented;
2707
    case TARGET_NR_nfsservctl:
2708
        goto unimplemented;
2709
    case TARGET_NR_prctl:
2710
        goto unimplemented;
2711
#ifdef TARGET_NR_pread
2712
    case TARGET_NR_pread:
2713
        page_unprotect_range((void *)arg2, arg3);
2714
        ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4));
2715
        break;
2716
    case TARGET_NR_pwrite:
2717
        ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
2718
        break;
2719
#endif
2720
    case TARGET_NR_getcwd:
2721
        ret = get_errno(sys_getcwd1((char *)arg1, arg2));
2722
        break;
2723
    case TARGET_NR_capget:
2724
        goto unimplemented;
2725
    case TARGET_NR_capset:
2726
        goto unimplemented;
2727
    case TARGET_NR_sigaltstack:
2728
        goto unimplemented;
2729
    case TARGET_NR_sendfile:
2730
        goto unimplemented;
2731
#ifdef TARGET_NR_getpmsg
2732
    case TARGET_NR_getpmsg:
2733
        goto unimplemented;
2734
#endif
2735
#ifdef TARGET_NR_putpmsg
2736
    case TARGET_NR_putpmsg:
2737
        goto unimplemented;
2738
#endif
2739
    case TARGET_NR_vfork:
2740
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
2741
        break;
2742
#ifdef TARGET_NR_ugetrlimit
2743
    case TARGET_NR_ugetrlimit:
2744
    {
2745
        struct rlimit rlim;
2746
        ret = get_errno(getrlimit(arg1, &rlim));
2747
        if (!is_error(ret)) {
2748
            struct target_rlimit *target_rlim = (void *)arg2;
2749
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2750
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
2751
        }
2752
        break;
2753
    }
2754
#endif
2755
#ifdef TARGET_NR_truncate64
2756
    case TARGET_NR_truncate64:
2757
        goto unimplemented;
2758
#endif
2759
#ifdef TARGET_NR_ftruncate64
2760
    case TARGET_NR_ftruncate64:
2761
        goto unimplemented;
2762
#endif
2763
#ifdef TARGET_NR_stat64
2764
    case TARGET_NR_stat64:
2765
        ret = get_errno(stat(path((const char *)arg1), &st));
2766
        goto do_stat64;
2767
#endif
2768
#ifdef TARGET_NR_lstat64
2769
    case TARGET_NR_lstat64:
2770
        ret = get_errno(lstat(path((const char *)arg1), &st));
2771
        goto do_stat64;
2772
#endif
2773
#ifdef TARGET_NR_fstat64
2774
    case TARGET_NR_fstat64:
2775
        {
2776
            ret = get_errno(fstat(arg1, &st));
2777
        do_stat64:
2778
            if (!is_error(ret)) {
2779
                struct target_stat64 *target_st = (void *)arg2;
2780
                memset(target_st, 0, sizeof(struct target_stat64));
2781
                put_user(st.st_dev, &target_st->st_dev);
2782
                put_user(st.st_ino, &target_st->st_ino);
2783
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
2784
                put_user(st.st_ino, &target_st->__st_ino);
2785
#endif
2786
                put_user(st.st_mode, &target_st->st_mode);
2787
                put_user(st.st_nlink, &target_st->st_nlink);
2788
                put_user(st.st_uid, &target_st->st_uid);
2789
                put_user(st.st_gid, &target_st->st_gid);
2790
                put_user(st.st_rdev, &target_st->st_rdev);
2791
                /* XXX: better use of kernel struct */
2792
                put_user(st.st_size, &target_st->st_size);
2793
                put_user(st.st_blksize, &target_st->st_blksize);
2794
                put_user(st.st_blocks, &target_st->st_blocks);
2795
                put_user(st.st_atime, &target_st->target_st_atime);
2796
                put_user(st.st_mtime, &target_st->target_st_mtime);
2797
                put_user(st.st_ctime, &target_st->target_st_ctime);
2798
            }
2799
        }
2800
        break;
2801
#endif
2802
#ifdef USE_UID16
2803
    case TARGET_NR_lchown:
2804
        ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2805
        break;
2806
    case TARGET_NR_getuid:
2807
        ret = get_errno(high2lowuid(getuid()));
2808
        break;
2809
    case TARGET_NR_getgid:
2810
        ret = get_errno(high2lowgid(getgid()));
2811
        break;
2812
    case TARGET_NR_geteuid:
2813
        ret = get_errno(high2lowuid(geteuid()));
2814
        break;
2815
    case TARGET_NR_getegid:
2816
        ret = get_errno(high2lowgid(getegid()));
2817
        break;
2818
    case TARGET_NR_setreuid:
2819
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
2820
        break;
2821
    case TARGET_NR_setregid:
2822
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
2823
        break;
2824
    case TARGET_NR_getgroups:
2825
        {
2826
            int gidsetsize = arg1;
2827
            uint16_t *target_grouplist = (void *)arg2;
2828
            gid_t *grouplist;
2829
            int i;
2830

    
2831
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2832
            ret = get_errno(getgroups(gidsetsize, grouplist));
2833
            if (!is_error(ret)) {
2834
                for(i = 0;i < gidsetsize; i++)
2835
                    target_grouplist[i] = tswap16(grouplist[i]);
2836
            }
2837
        }
2838
        break;
2839
    case TARGET_NR_setgroups:
2840
        {
2841
            int gidsetsize = arg1;
2842
            uint16_t *target_grouplist = (void *)arg2;
2843
            gid_t *grouplist;
2844
            int i;
2845

    
2846
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2847
            for(i = 0;i < gidsetsize; i++)
2848
                grouplist[i] = tswap16(target_grouplist[i]);
2849
            ret = get_errno(setgroups(gidsetsize, grouplist));
2850
        }
2851
        break;
2852
    case TARGET_NR_fchown:
2853
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
2854
        break;
2855
#ifdef TARGET_NR_setresuid
2856
    case TARGET_NR_setresuid:
2857
        ret = get_errno(setresuid(low2highuid(arg1), 
2858
                                  low2highuid(arg2), 
2859
                                  low2highuid(arg3)));
2860
        break;
2861
#endif
2862
#ifdef TARGET_NR_getresuid
2863
    case TARGET_NR_getresuid:
2864
        {
2865
            int ruid, euid, suid;
2866
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2867
            if (!is_error(ret)) {
2868
                *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
2869
                *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
2870
                *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
2871
            }
2872
        }
2873
        break;
2874
#endif
2875
#ifdef TARGET_NR_getresgid
2876
    case TARGET_NR_setresgid:
2877
        ret = get_errno(setresgid(low2highgid(arg1), 
2878
                                  low2highgid(arg2), 
2879
                                  low2highgid(arg3)));
2880
        break;
2881
#endif
2882
#ifdef TARGET_NR_getresgid
2883
    case TARGET_NR_getresgid:
2884
        {
2885
            int rgid, egid, sgid;
2886
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
2887
            if (!is_error(ret)) {
2888
                *(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
2889
                *(uint16_t *)arg2 = tswap16(high2lowgid(egid));
2890
                *(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
2891
            }
2892
        }
2893
        break;
2894
#endif
2895
    case TARGET_NR_chown:
2896
        ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2897
        break;
2898
    case TARGET_NR_setuid:
2899
        ret = get_errno(setuid(low2highuid(arg1)));
2900
        break;
2901
    case TARGET_NR_setgid:
2902
        ret = get_errno(setgid(low2highgid(arg1)));
2903
        break;
2904
    case TARGET_NR_setfsuid:
2905
        ret = get_errno(setfsuid(arg1));
2906
        break;
2907
    case TARGET_NR_setfsgid:
2908
        ret = get_errno(setfsgid(arg1));
2909
        break;
2910
#endif /* USE_UID16 */
2911

    
2912
#ifdef TARGET_NR_lchown32
2913
    case TARGET_NR_lchown32:
2914
        ret = get_errno(lchown((const char *)arg1, arg2, arg3));
2915
        break;
2916
#endif
2917
#ifdef TARGET_NR_getuid32
2918
    case TARGET_NR_getuid32:
2919
        ret = get_errno(getuid());
2920
        break;
2921
#endif
2922
#ifdef TARGET_NR_getgid32
2923
    case TARGET_NR_getgid32:
2924
        ret = get_errno(getgid());
2925
        break;
2926
#endif
2927
#ifdef TARGET_NR_geteuid32
2928
    case TARGET_NR_geteuid32:
2929
        ret = get_errno(geteuid());
2930
        break;
2931
#endif
2932
#ifdef TARGET_NR_getegid32
2933
    case TARGET_NR_getegid32:
2934
        ret = get_errno(getegid());
2935
        break;
2936
#endif
2937
#ifdef TARGET_NR_setreuid32
2938
    case TARGET_NR_setreuid32:
2939
        ret = get_errno(setreuid(arg1, arg2));
2940
        break;
2941
#endif
2942
#ifdef TARGET_NR_setregid32
2943
    case TARGET_NR_setregid32:
2944
        ret = get_errno(setregid(arg1, arg2));
2945
        break;
2946
#endif
2947
#ifdef TARGET_NR_getgroups32
2948
    case TARGET_NR_getgroups32:
2949
        {
2950
            int gidsetsize = arg1;
2951
            uint32_t *target_grouplist = (void *)arg2;
2952
            gid_t *grouplist;
2953
            int i;
2954

    
2955
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2956
            ret = get_errno(getgroups(gidsetsize, grouplist));
2957
            if (!is_error(ret)) {
2958
                for(i = 0;i < gidsetsize; i++)
2959
                    put_user(grouplist[i], &target_grouplist[i]);
2960
            }
2961
        }
2962
        break;
2963
#endif
2964
#ifdef TARGET_NR_setgroups32
2965
    case TARGET_NR_setgroups32:
2966
        {
2967
            int gidsetsize = arg1;
2968
            uint32_t *target_grouplist = (void *)arg2;
2969
            gid_t *grouplist;
2970
            int i;
2971
            
2972
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2973
            for(i = 0;i < gidsetsize; i++)
2974
                get_user(grouplist[i], &target_grouplist[i]);
2975
            ret = get_errno(setgroups(gidsetsize, grouplist));
2976
        }
2977
        break;
2978
#endif
2979
#ifdef TARGET_NR_fchown32
2980
    case TARGET_NR_fchown32:
2981
        ret = get_errno(fchown(arg1, arg2, arg3));
2982
        break;
2983
#endif
2984
#ifdef TARGET_NR_setresuid32
2985
    case TARGET_NR_setresuid32:
2986
        ret = get_errno(setresuid(arg1, arg2, arg3));
2987
        break;
2988
#endif
2989
#ifdef TARGET_NR_getresuid32
2990
    case TARGET_NR_getresuid32:
2991
        {
2992
            int ruid, euid, suid;
2993
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2994
            if (!is_error(ret)) {
2995
                *(uint32_t *)arg1 = tswap32(ruid);
2996
                *(uint32_t *)arg2 = tswap32(euid);
2997
                *(uint32_t *)arg3 = tswap32(suid);
2998
            }
2999
        }
3000
        break;
3001
#endif
3002
#ifdef TARGET_NR_setresgid32
3003
    case TARGET_NR_setresgid32:
3004
        ret = get_errno(setresgid(arg1, arg2, arg3));
3005
        break;
3006
#endif
3007
#ifdef TARGET_NR_getresgid32
3008
    case TARGET_NR_getresgid32:
3009
        {
3010
            int rgid, egid, sgid;
3011
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
3012
            if (!is_error(ret)) {
3013
                *(uint32_t *)arg1 = tswap32(rgid);
3014
                *(uint32_t *)arg2 = tswap32(egid);
3015
                *(uint32_t *)arg3 = tswap32(sgid);
3016
            }
3017
        }
3018
        break;
3019
#endif
3020
#ifdef TARGET_NR_chown32
3021
    case TARGET_NR_chown32:
3022
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
3023
        break;
3024
#endif
3025
#ifdef TARGET_NR_setuid32
3026
    case TARGET_NR_setuid32:
3027
        ret = get_errno(setuid(arg1));
3028
        break;
3029
#endif
3030
#ifdef TARGET_NR_setgid32
3031
    case TARGET_NR_setgid32:
3032
        ret = get_errno(setgid(arg1));
3033
        break;
3034
#endif
3035
#ifdef TARGET_NR_setfsuid32
3036
    case TARGET_NR_setfsuid32:
3037
        ret = get_errno(setfsuid(arg1));
3038
        break;
3039
#endif
3040
#ifdef TARGET_NR_setfsgid32
3041
    case TARGET_NR_setfsgid32:
3042
        ret = get_errno(setfsgid(arg1));
3043
        break;
3044
#endif
3045

    
3046
    case TARGET_NR_pivot_root:
3047
        goto unimplemented;
3048
#ifdef TARGET_NR_mincore
3049
    case TARGET_NR_mincore:
3050
        goto unimplemented;
3051
#endif
3052
#ifdef TARGET_NR_madvise
3053
    case TARGET_NR_madvise:
3054
        goto unimplemented;
3055
#endif
3056
#if TARGET_LONG_BITS == 32
3057
    case TARGET_NR_fcntl64:
3058
    {
3059
        struct flock64 fl;
3060
        struct target_flock64 *target_fl = (void *)arg3;
3061

    
3062
        switch(arg2) {
3063
        case F_GETLK64:
3064
            ret = get_errno(fcntl(arg1, arg2, &fl));
3065
            if (ret == 0) {
3066
                target_fl->l_type = tswap16(fl.l_type);
3067
                target_fl->l_whence = tswap16(fl.l_whence);
3068
                target_fl->l_start = tswap64(fl.l_start);
3069
                target_fl->l_len = tswap64(fl.l_len);
3070
                target_fl->l_pid = tswapl(fl.l_pid);
3071
            }
3072
            break;
3073

    
3074
        case F_SETLK64:
3075
        case F_SETLKW64:
3076
            fl.l_type = tswap16(target_fl->l_type);
3077
            fl.l_whence = tswap16(target_fl->l_whence);
3078
            fl.l_start = tswap64(target_fl->l_start);
3079
            fl.l_len = tswap64(target_fl->l_len);
3080
            fl.l_pid = tswapl(target_fl->l_pid);
3081
            ret = get_errno(fcntl(arg1, arg2, &fl));
3082
            break;
3083
        default:
3084
            ret = get_errno(do_fcntl(arg1, arg2, arg3));
3085
            break;
3086
        }
3087
        break;
3088
    }
3089
#endif
3090
#ifdef TARGET_NR_security
3091
    case TARGET_NR_security:
3092
        goto unimplemented;
3093
#endif
3094
#ifdef TARGET_NR_getpagesize
3095
    case TARGET_NR_getpagesize:
3096
        ret = TARGET_PAGE_SIZE;
3097
        break;
3098
#endif
3099
    case TARGET_NR_gettid:
3100
        ret = get_errno(gettid());
3101
        break;
3102
    case TARGET_NR_readahead:
3103
        goto unimplemented;
3104
#ifdef TARGET_NR_setxattr
3105
    case TARGET_NR_setxattr:
3106
    case TARGET_NR_lsetxattr:
3107
    case TARGET_NR_fsetxattr:
3108
    case TARGET_NR_getxattr:
3109
    case TARGET_NR_lgetxattr:
3110
    case TARGET_NR_fgetxattr:
3111
    case TARGET_NR_listxattr:
3112
    case TARGET_NR_llistxattr:
3113
    case TARGET_NR_flistxattr:
3114
    case TARGET_NR_removexattr:
3115
    case TARGET_NR_lremovexattr:
3116
    case TARGET_NR_fremovexattr:
3117
        goto unimplemented_nowarn;
3118
#endif
3119
#ifdef TARGET_NR_set_thread_area
3120
    case TARGET_NR_set_thread_area:
3121
    case TARGET_NR_get_thread_area:
3122
        goto unimplemented_nowarn;
3123
#endif
3124
    default:
3125
    unimplemented:
3126
        gemu_log("qemu: Unsupported syscall: %d\n", num);
3127
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area)
3128
    unimplemented_nowarn:
3129
#endif
3130
        ret = -ENOSYS;
3131
        break;
3132
    }
3133
 fail:
3134
#ifdef DEBUG
3135
    gemu_log(" = %ld\n", ret);
3136
#endif
3137
    return ret;
3138
}
3139