Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ afc7df11

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
881

    
882
#define N_SHM_REGIONS        32
883

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

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

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

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

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

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

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

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

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

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

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

    
996
#define MAX_STRUCT_SIZE 4096
997

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

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

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

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

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

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

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

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

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

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

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

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

    
1273
#if defined(TARGET_I386)
1274

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1512
#ifdef USE_UID16
1513

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

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

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

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

    
1546
#endif /* USE_UID16 */
1547

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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