Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 2efbe911

History | View | Annotate | Download (99.5 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
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_TOS:
551
        case IP_TTL:
552
        case IP_HDRINCL:
553
        case IP_ROUTER_ALERT:
554
        case IP_RECVOPTS:
555
        case IP_RETOPTS:
556
        case IP_PKTINFO:
557
        case IP_MTU_DISCOVER:
558
        case IP_RECVERR:
559
        case IP_RECVTOS:
560
#ifdef IP_FREEBIND
561
        case IP_FREEBIND:
562
#endif
563
        case IP_MULTICAST_TTL:
564
        case IP_MULTICAST_LOOP:
565
            val = 0;
566
            if (optlen >= sizeof(uint32_t)) {
567
                if (get_user(val, (uint32_t *)optval))
568
                    return -EFAULT;
569
            } else if (optlen >= 1) {
570
                if (get_user(val, (uint8_t *)optval))
571
                    return -EFAULT;
572
            }
573
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
574
            break;
575
        default:
576
            goto unimplemented;
577
        }
578
        break;
579
    case SOL_SOCKET:
580
        switch (optname) {
581
            /* Options with 'int' argument.  */
582
        case SO_DEBUG:
583
        case SO_REUSEADDR:
584
        case SO_TYPE:
585
        case SO_ERROR:
586
        case SO_DONTROUTE:
587
        case SO_BROADCAST:
588
        case SO_SNDBUF:
589
        case SO_RCVBUF:
590
        case SO_KEEPALIVE:
591
        case SO_OOBINLINE:
592
        case SO_NO_CHECK:
593
        case SO_PRIORITY:
594
#ifdef SO_BSDCOMPAT
595
        case SO_BSDCOMPAT:
596
#endif
597
        case SO_PASSCRED:
598
        case SO_TIMESTAMP:
599
        case SO_RCVLOWAT:
600
        case SO_RCVTIMEO:
601
        case SO_SNDTIMEO:
602
            if (optlen < sizeof(uint32_t))
603
                return -EINVAL;
604
            if (get_user(val, (uint32_t *)optval))
605
                return -EFAULT;
606
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
607
            break;
608
        default:
609
            goto unimplemented;
610
        }
611
        break;
612
    default:
613
    unimplemented:
614
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
615
        ret = -ENOSYS;
616
    }
617
    return ret;
618
}
619

    
620
static long do_getsockopt(int sockfd, int level, int optname, 
621
                          void *optval, socklen_t *optlen)
622
{
623
    int len, lv, val, ret;
624

    
625
    switch(level) {
626
    case SOL_SOCKET:
627
        switch (optname) {
628
        case SO_LINGER:
629
        case SO_RCVTIMEO:
630
        case SO_SNDTIMEO:
631
        case SO_PEERCRED:
632
        case SO_PEERNAME:
633
            /* These don't just return a single integer */
634
            goto unimplemented;
635
        default:
636
            goto int_case;
637
        }
638
        break;
639
    case SOL_TCP:
640
        /* TCP options all take an 'int' value.  */
641
    int_case:
642
        if (get_user(len, optlen))
643
            return -EFAULT;
644
        if (len < 0)
645
            return -EINVAL;
646
        lv = sizeof(int);
647
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
648
        if (ret < 0)
649
            return ret;
650
        val = tswap32(val);
651
        if (len > lv)
652
            len = lv;
653
        if (copy_to_user(optval, &val, len))
654
            return -EFAULT;
655
        if (put_user(len, optlen))
656
            return -EFAULT;
657
        break;
658
    case SOL_IP:
659
        switch(optname) {
660
        case IP_TOS:
661
        case IP_TTL:
662
        case IP_HDRINCL:
663
        case IP_ROUTER_ALERT:
664
        case IP_RECVOPTS:
665
        case IP_RETOPTS:
666
        case IP_PKTINFO:
667
        case IP_MTU_DISCOVER:
668
        case IP_RECVERR:
669
        case IP_RECVTOS:
670
#ifdef IP_FREEBIND
671
        case IP_FREEBIND:
672
#endif
673
        case IP_MULTICAST_TTL:
674
        case IP_MULTICAST_LOOP:
675
            if (get_user(len, optlen))
676
                return -EFAULT;
677
            if (len < 0)
678
                return -EINVAL;
679
            lv = sizeof(int);
680
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
681
            if (ret < 0)
682
                return ret;
683
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
684
                unsigned char ucval = val;
685
                len = 1;
686
                if (put_user(len, optlen))
687
                    return -EFAULT;
688
                if (copy_to_user(optval,&ucval,1))
689
                    return -EFAULT;
690
            } else {
691
                val = tswap32(val);
692
                if (len > sizeof(int))
693
                    len = sizeof(int);
694
                if (put_user(len, optlen))
695
                    return -EFAULT;
696
                if (copy_to_user(optval, &val, len))
697
                    return -EFAULT;
698
            }
699
            break;
700
        default:
701
            goto unimplemented;
702
        }
703
        break;
704
    default:
705
    unimplemented:
706
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
707
                 level, optname);
708
        ret = -ENOSYS;
709
        break;
710
    }
711
    return ret;
712
}
713

    
714
static long do_socketcall(int num, int32_t *vptr)
715
{
716
    long ret;
717

    
718
    switch(num) {
719
    case SOCKOP_socket:
720
        {
721
            int domain = tswap32(vptr[0]);
722
            int type = tswap32(vptr[1]);
723
            int protocol = tswap32(vptr[2]);
724

    
725
            ret = get_errno(socket(domain, type, protocol));
726
        }
727
        break;
728
    case SOCKOP_bind:
729
        {
730
            int sockfd = tswap32(vptr[0]);
731
            void *target_addr = (void *)tswap32(vptr[1]);
732
            socklen_t addrlen = tswap32(vptr[2]);
733
            void *addr = alloca(addrlen);
734

    
735
            target_to_host_sockaddr(addr, target_addr, addrlen);
736
            ret = get_errno(bind(sockfd, addr, addrlen));
737
        }
738
        break;
739
    case SOCKOP_connect:
740
        {
741
            int sockfd = tswap32(vptr[0]);
742
            void *target_addr = (void *)tswap32(vptr[1]);
743
            socklen_t addrlen = tswap32(vptr[2]);
744
            void *addr = alloca(addrlen);
745

    
746
            target_to_host_sockaddr(addr, target_addr, addrlen);
747
            ret = get_errno(connect(sockfd, addr, addrlen));
748
        }
749
        break;
750
    case SOCKOP_listen:
751
        {
752
            int sockfd = tswap32(vptr[0]);
753
            int backlog = tswap32(vptr[1]);
754

    
755
            ret = get_errno(listen(sockfd, backlog));
756
        }
757
        break;
758
    case SOCKOP_accept:
759
        {
760
            int sockfd = tswap32(vptr[0]);
761
            void *target_addr = (void *)tswap32(vptr[1]);
762
            uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
763
            socklen_t addrlen = tswap32(*target_addrlen);
764
            void *addr = alloca(addrlen);
765

    
766
            ret = get_errno(accept(sockfd, addr, &addrlen));
767
            if (!is_error(ret)) {
768
                host_to_target_sockaddr(target_addr, addr, addrlen);
769
                *target_addrlen = tswap32(addrlen);
770
            }
771
        }
772
        break;
773
    case SOCKOP_getsockname:
774
        {
775
            int sockfd = tswap32(vptr[0]);
776
            void *target_addr = (void *)tswap32(vptr[1]);
777
            uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
778
            socklen_t addrlen = tswap32(*target_addrlen);
779
            void *addr = alloca(addrlen);
780

    
781
            ret = get_errno(getsockname(sockfd, addr, &addrlen));
782
            if (!is_error(ret)) {
783
                host_to_target_sockaddr(target_addr, addr, addrlen);
784
                *target_addrlen = tswap32(addrlen);
785
            }
786
        }
787
        break;
788
    case SOCKOP_getpeername:
789
        {
790
            int sockfd = tswap32(vptr[0]);
791
            void *target_addr = (void *)tswap32(vptr[1]);
792
            uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
793
            socklen_t addrlen = tswap32(*target_addrlen);
794
            void *addr = alloca(addrlen);
795

    
796
            ret = get_errno(getpeername(sockfd, addr, &addrlen));
797
            if (!is_error(ret)) {
798
                host_to_target_sockaddr(target_addr, addr, addrlen);
799
                *target_addrlen = tswap32(addrlen);
800
            }
801
        }
802
        break;
803
    case SOCKOP_socketpair:
804
        {
805
            int domain = tswap32(vptr[0]);
806
            int type = tswap32(vptr[1]);
807
            int protocol = tswap32(vptr[2]);
808
            int32_t *target_tab = (void *)tswap32(vptr[3]);
809
            int tab[2];
810

    
811
            ret = get_errno(socketpair(domain, type, protocol, tab));
812
            if (!is_error(ret)) {
813
                target_tab[0] = tswap32(tab[0]);
814
                target_tab[1] = tswap32(tab[1]);
815
            }
816
        }
817
        break;
818
    case SOCKOP_send:
819
        {
820
            int sockfd = tswap32(vptr[0]);
821
            void *msg = (void *)tswap32(vptr[1]);
822
            size_t len = tswap32(vptr[2]);
823
            int flags = tswap32(vptr[3]);
824

    
825
            ret = get_errno(send(sockfd, msg, len, flags));
826
        }
827
        break;
828
    case SOCKOP_recv:
829
        {
830
            int sockfd = tswap32(vptr[0]);
831
            void *msg = (void *)tswap32(vptr[1]);
832
            size_t len = tswap32(vptr[2]);
833
            int flags = tswap32(vptr[3]);
834

    
835
            ret = get_errno(recv(sockfd, msg, len, flags));
836
        }
837
        break;
838
    case SOCKOP_sendto:
839
        {
840
            int sockfd = tswap32(vptr[0]);
841
            void *msg = (void *)tswap32(vptr[1]);
842
            size_t len = tswap32(vptr[2]);
843
            int flags = tswap32(vptr[3]);
844
            void *target_addr = (void *)tswap32(vptr[4]);
845
            socklen_t addrlen = tswap32(vptr[5]);
846
            void *addr = alloca(addrlen);
847

    
848
            target_to_host_sockaddr(addr, target_addr, addrlen);
849
            ret = get_errno(sendto(sockfd, msg, len, flags, addr, addrlen));
850
        }
851
        break;
852
    case SOCKOP_recvfrom:
853
        {
854
            int sockfd = tswap32(vptr[0]);
855
            void *msg = (void *)tswap32(vptr[1]);
856
            size_t len = tswap32(vptr[2]);
857
            int flags = tswap32(vptr[3]);
858
            void *target_addr = (void *)tswap32(vptr[4]);
859
            uint32_t *target_addrlen = (void *)tswap32(vptr[5]);
860
            socklen_t addrlen = tswap32(*target_addrlen);
861
            void *addr = alloca(addrlen);
862

    
863
            ret = get_errno(recvfrom(sockfd, msg, len, flags, addr, &addrlen));
864
            if (!is_error(ret)) {
865
                host_to_target_sockaddr(target_addr, addr, addrlen);
866
                *target_addrlen = tswap32(addrlen);
867
            }
868
        }
869
        break;
870
    case SOCKOP_shutdown:
871
        {
872
            int sockfd = tswap32(vptr[0]);
873
            int how = tswap32(vptr[1]);
874

    
875
            ret = get_errno(shutdown(sockfd, how));
876
        }
877
        break;
878
    case SOCKOP_sendmsg:
879
    case SOCKOP_recvmsg:
880
        {
881
            int fd;
882
            struct target_msghdr *msgp;
883
            struct msghdr msg;
884
            int flags, count, i;
885
            struct iovec *vec;
886
            struct target_iovec *target_vec;
887

    
888
            msgp = (void *)tswap32(vptr[1]);
889
            msg.msg_name = (void *)tswapl(msgp->msg_name);
890
            msg.msg_namelen = tswapl(msgp->msg_namelen);
891
            msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
892
            msg.msg_control = alloca(msg.msg_controllen);
893
            msg.msg_flags = tswap32(msgp->msg_flags);
894

    
895
            count = tswapl(msgp->msg_iovlen);
896
            vec = alloca(count * sizeof(struct iovec));
897
            target_vec = (void *)tswapl(msgp->msg_iov);
898
            for(i = 0;i < count; i++) {
899
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
900
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
901
            }
902
            msg.msg_iovlen = count;
903
            msg.msg_iov = vec;
904

    
905
            fd = tswap32(vptr[0]);
906
            flags = tswap32(vptr[2]);
907
            if (num == SOCKOP_sendmsg) {
908
                target_to_host_cmsg(&msg, msgp);
909
                ret = get_errno(sendmsg(fd, &msg, flags));
910
            } else {
911
                ret = get_errno(recvmsg(fd, &msg, flags));
912
                if (!is_error(ret))
913
                  host_to_target_cmsg(msgp, &msg);
914
            }
915
        }
916
        break;
917
    case SOCKOP_setsockopt:
918
        {
919
            int sockfd = tswap32(vptr[0]);
920
            int level = tswap32(vptr[1]);
921
            int optname = tswap32(vptr[2]);
922
            void *optval = (void *)tswap32(vptr[3]);
923
            socklen_t optlen = tswap32(vptr[4]);
924

    
925
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
926
        }
927
        break;
928
    case SOCKOP_getsockopt:
929
        {
930
            int sockfd = tswap32(vptr[0]);
931
            int level = tswap32(vptr[1]);
932
            int optname = tswap32(vptr[2]);
933
            void *optval = (void *)tswap32(vptr[3]);
934
            uint32_t *poptlen = (void *)tswap32(vptr[4]);
935

    
936
            ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
937
        }
938
        break;
939
    default:
940
        gemu_log("Unsupported socketcall: %d\n", num);
941
        ret = -ENOSYS;
942
        break;
943
    }
944
    return ret;
945
}
946

    
947

    
948
#define N_SHM_REGIONS        32
949

    
950
static struct shm_region {
951
    uint32_t        start;
952
    uint32_t        size;
953
} shm_regions[N_SHM_REGIONS];
954

    
955
static long do_ipc(long call, long first, long second, long third,
956
                   long ptr, long fifth)
957
{
958
    int version;
959
    long ret = 0;
960
    unsigned long raddr;
961
    struct shmid_ds shm_info;
962
    int i;
963

    
964
    version = call >> 16;
965
    call &= 0xffff;
966

    
967
    switch (call) {
968
    case IPCOP_shmat:
969
        /* SHM_* flags are the same on all linux platforms */
970
        ret = get_errno((long) shmat(first, (void *) ptr, second));
971
        if (is_error(ret))
972
            break;
973
        raddr = ret;
974
        /* find out the length of the shared memory segment */
975
        
976
        ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
977
        if (is_error(ret)) {
978
            /* can't get length, bail out */
979
            shmdt((void *) raddr);
980
            break;
981
        }
982
        page_set_flags(raddr, raddr + shm_info.shm_segsz,
983
                       PAGE_VALID | PAGE_READ |
984
                       ((second & SHM_RDONLY)? 0: PAGE_WRITE));
985
        for (i = 0; i < N_SHM_REGIONS; ++i) {
986
            if (shm_regions[i].start == 0) {
987
                shm_regions[i].start = raddr;
988
                shm_regions[i].size = shm_info.shm_segsz;
989
                break;
990
            }
991
        }
992
        if (put_user(raddr, (uint32_t *)third))
993
            return -EFAULT;
994
        ret = 0;
995
        break;
996
    case IPCOP_shmdt:
997
        for (i = 0; i < N_SHM_REGIONS; ++i) {
998
            if (shm_regions[i].start == ptr) {
999
                shm_regions[i].start = 0;
1000
                page_set_flags(ptr, shm_regions[i].size, 0);
1001
                break;
1002
            }
1003
        }
1004
        ret = get_errno(shmdt((void *) ptr));
1005
        break;
1006

    
1007
    case IPCOP_shmget:
1008
        /* IPC_* flag values are the same on all linux platforms */
1009
        ret = get_errno(shmget(first, second, third));
1010
        break;
1011

    
1012
        /* IPC_* and SHM_* command values are the same on all linux platforms */
1013
    case IPCOP_shmctl:
1014
        switch(second) {
1015
        case IPC_RMID:
1016
        case SHM_LOCK:
1017
        case SHM_UNLOCK:
1018
            ret = get_errno(shmctl(first, second, NULL));
1019
            break;
1020
        default:
1021
            goto unimplemented;
1022
        }
1023
        break;
1024
    default:
1025
    unimplemented:
1026
        gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
1027
        ret = -ENOSYS;
1028
        break;
1029
    }
1030
    return ret;
1031
}
1032

    
1033
/* kernel structure types definitions */
1034
#define IFNAMSIZ        16
1035

    
1036
#define STRUCT(name, list...) STRUCT_ ## name,
1037
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
1038
enum {
1039
#include "syscall_types.h"
1040
};
1041
#undef STRUCT
1042
#undef STRUCT_SPECIAL
1043

    
1044
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
1045
#define STRUCT_SPECIAL(name)
1046
#include "syscall_types.h"
1047
#undef STRUCT
1048
#undef STRUCT_SPECIAL
1049

    
1050
typedef struct IOCTLEntry {
1051
    unsigned int target_cmd;
1052
    unsigned int host_cmd;
1053
    const char *name;
1054
    int access;
1055
    const argtype arg_type[5];
1056
} IOCTLEntry;
1057

    
1058
#define IOC_R 0x0001
1059
#define IOC_W 0x0002
1060
#define IOC_RW (IOC_R | IOC_W)
1061

    
1062
#define MAX_STRUCT_SIZE 4096
1063

    
1064
IOCTLEntry ioctl_entries[] = {
1065
#define IOCTL(cmd, access, types...) \
1066
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
1067
#include "ioctls.h"
1068
    { 0, 0, },
1069
};
1070

    
1071
static long do_ioctl(long fd, long cmd, long arg)
1072
{
1073
    const IOCTLEntry *ie;
1074
    const argtype *arg_type;
1075
    long ret;
1076
    uint8_t buf_temp[MAX_STRUCT_SIZE];
1077

    
1078
    ie = ioctl_entries;
1079
    for(;;) {
1080
        if (ie->target_cmd == 0) {
1081
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
1082
            return -ENOSYS;
1083
        }
1084
        if (ie->target_cmd == cmd)
1085
            break;
1086
        ie++;
1087
    }
1088
    arg_type = ie->arg_type;
1089
#if defined(DEBUG)
1090
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
1091
#endif
1092
    switch(arg_type[0]) {
1093
    case TYPE_NULL:
1094
        /* no argument */
1095
        ret = get_errno(ioctl(fd, ie->host_cmd));
1096
        break;
1097
    case TYPE_PTRVOID:
1098
    case TYPE_INT:
1099
        /* int argment */
1100
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
1101
        break;
1102
    case TYPE_PTR:
1103
        arg_type++;
1104
        switch(ie->access) {
1105
        case IOC_R:
1106
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1107
            if (!is_error(ret)) {
1108
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
1109
            }
1110
            break;
1111
        case IOC_W:
1112
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
1113
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1114
            break;
1115
        default:
1116
        case IOC_RW:
1117
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
1118
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1119
            if (!is_error(ret)) {
1120
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
1121
            }
1122
            break;
1123
        }
1124
        break;
1125
    default:
1126
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
1127
        ret = -ENOSYS;
1128
        break;
1129
    }
1130
    return ret;
1131
}
1132

    
1133
bitmask_transtbl iflag_tbl[] = {
1134
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
1135
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
1136
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
1137
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
1138
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
1139
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
1140
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
1141
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
1142
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
1143
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
1144
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
1145
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
1146
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
1147
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
1148
        { 0, 0, 0, 0 }
1149
};
1150

    
1151
bitmask_transtbl oflag_tbl[] = {
1152
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
1153
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
1154
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
1155
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
1156
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
1157
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
1158
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
1159
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
1160
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
1161
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
1162
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
1163
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
1164
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
1165
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
1166
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
1167
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
1168
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
1169
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
1170
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
1171
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
1172
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
1173
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
1174
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
1175
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
1176
        { 0, 0, 0, 0 }
1177
};
1178

    
1179
bitmask_transtbl cflag_tbl[] = {
1180
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
1181
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
1182
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
1183
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
1184
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
1185
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
1186
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
1187
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
1188
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
1189
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
1190
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
1191
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
1192
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
1193
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
1194
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
1195
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
1196
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
1197
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
1198
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
1199
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
1200
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
1201
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
1202
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
1203
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
1204
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
1205
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
1206
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
1207
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
1208
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
1209
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
1210
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
1211
        { 0, 0, 0, 0 }
1212
};
1213

    
1214
bitmask_transtbl lflag_tbl[] = {
1215
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
1216
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
1217
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
1218
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
1219
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
1220
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
1221
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
1222
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
1223
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
1224
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
1225
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
1226
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
1227
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
1228
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
1229
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
1230
        { 0, 0, 0, 0 }
1231
};
1232

    
1233
static void target_to_host_termios (void *dst, const void *src)
1234
{
1235
    struct host_termios *host = dst;
1236
    const struct target_termios *target = src;
1237
    
1238
    host->c_iflag = 
1239
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1240
    host->c_oflag = 
1241
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1242
    host->c_cflag = 
1243
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1244
    host->c_lflag = 
1245
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
1246
    host->c_line = target->c_line;
1247
    
1248
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 
1249
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 
1250
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];       
1251
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 
1252
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];   
1253
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 
1254
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];   
1255
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 
1256
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];       
1257
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 
1258
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 
1259
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];   
1260
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];   
1261
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];   
1262
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];     
1263
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];       
1264
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 
1265
}
1266
  
1267
static void host_to_target_termios (void *dst, const void *src)
1268
{
1269
    struct target_termios *target = dst;
1270
    const struct host_termios *host = src;
1271

    
1272
    target->c_iflag = 
1273
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1274
    target->c_oflag = 
1275
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1276
    target->c_cflag = 
1277
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1278
    target->c_lflag = 
1279
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
1280
    target->c_line = host->c_line;
1281
  
1282
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
1283
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
1284
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
1285
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
1286
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
1287
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
1288
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
1289
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
1290
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
1291
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
1292
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
1293
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
1294
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
1295
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
1296
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
1297
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
1298
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
1299
}
1300

    
1301
StructEntry struct_termios_def = {
1302
    .convert = { host_to_target_termios, target_to_host_termios },
1303
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
1304
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
1305
};
1306

    
1307
static bitmask_transtbl mmap_flags_tbl[] = {
1308
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
1309
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
1310
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
1311
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
1312
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
1313
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
1314
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
1315
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
1316
        { 0, 0, 0, 0 }
1317
};
1318

    
1319
static bitmask_transtbl fcntl_flags_tbl[] = {
1320
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
1321
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
1322
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
1323
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
1324
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
1325
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
1326
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
1327
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
1328
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
1329
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
1330
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
1331
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
1332
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
1333
#if defined(O_DIRECT)
1334
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
1335
#endif
1336
        { 0, 0, 0, 0 }
1337
};
1338

    
1339
#if defined(TARGET_I386)
1340

    
1341
/* NOTE: there is really one LDT for all the threads */
1342
uint8_t *ldt_table;
1343

    
1344
static int read_ldt(void *ptr, unsigned long bytecount)
1345
{
1346
    int size;
1347

    
1348
    if (!ldt_table)
1349
        return 0;
1350
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
1351
    if (size > bytecount)
1352
        size = bytecount;
1353
    memcpy(ptr, ldt_table, size);
1354
    return size;
1355
}
1356

    
1357
/* XXX: add locking support */
1358
static int write_ldt(CPUX86State *env, 
1359
                     void *ptr, unsigned long bytecount, int oldmode)
1360
{
1361
    struct target_modify_ldt_ldt_s ldt_info;
1362
    int seg_32bit, contents, read_exec_only, limit_in_pages;
1363
    int seg_not_present, useable;
1364
    uint32_t *lp, entry_1, entry_2;
1365

    
1366
    if (bytecount != sizeof(ldt_info))
1367
        return -EINVAL;
1368
    memcpy(&ldt_info, ptr, sizeof(ldt_info));
1369
    tswap32s(&ldt_info.entry_number);
1370
    tswapls((long *)&ldt_info.base_addr);
1371
    tswap32s(&ldt_info.limit);
1372
    tswap32s(&ldt_info.flags);
1373
    
1374
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1375
        return -EINVAL;
1376
    seg_32bit = ldt_info.flags & 1;
1377
    contents = (ldt_info.flags >> 1) & 3;
1378
    read_exec_only = (ldt_info.flags >> 3) & 1;
1379
    limit_in_pages = (ldt_info.flags >> 4) & 1;
1380
    seg_not_present = (ldt_info.flags >> 5) & 1;
1381
    useable = (ldt_info.flags >> 6) & 1;
1382

    
1383
    if (contents == 3) {
1384
        if (oldmode)
1385
            return -EINVAL;
1386
        if (seg_not_present == 0)
1387
            return -EINVAL;
1388
    }
1389
    /* allocate the LDT */
1390
    if (!ldt_table) {
1391
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1392
        if (!ldt_table)
1393
            return -ENOMEM;
1394
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1395
        env->ldt.base = (long)ldt_table;
1396
        env->ldt.limit = 0xffff;
1397
    }
1398

    
1399
    /* NOTE: same code as Linux kernel */
1400
    /* Allow LDTs to be cleared by the user. */
1401
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
1402
        if (oldmode ||
1403
            (contents == 0                &&
1404
             read_exec_only == 1        &&
1405
             seg_32bit == 0                &&
1406
             limit_in_pages == 0        &&
1407
             seg_not_present == 1        &&
1408
             useable == 0 )) {
1409
            entry_1 = 0;
1410
            entry_2 = 0;
1411
            goto install;
1412
        }
1413
    }
1414
    
1415
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
1416
        (ldt_info.limit & 0x0ffff);
1417
    entry_2 = (ldt_info.base_addr & 0xff000000) |
1418
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
1419
        (ldt_info.limit & 0xf0000) |
1420
        ((read_exec_only ^ 1) << 9) |
1421
        (contents << 10) |
1422
        ((seg_not_present ^ 1) << 15) |
1423
        (seg_32bit << 22) |
1424
        (limit_in_pages << 23) |
1425
        0x7000;
1426
    if (!oldmode)
1427
        entry_2 |= (useable << 20);
1428

    
1429
    /* Install the new entry ...  */
1430
install:
1431
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
1432
    lp[0] = tswap32(entry_1);
1433
    lp[1] = tswap32(entry_2);
1434
    return 0;
1435
}
1436

    
1437
/* specific and weird i386 syscalls */
1438
int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
1439
{
1440
    int ret = -ENOSYS;
1441
    
1442
    switch (func) {
1443
    case 0:
1444
        ret = read_ldt(ptr, bytecount);
1445
        break;
1446
    case 1:
1447
        ret = write_ldt(env, ptr, bytecount, 1);
1448
        break;
1449
    case 0x11:
1450
        ret = write_ldt(env, ptr, bytecount, 0);
1451
        break;
1452
    }
1453
    return ret;
1454
}
1455

    
1456
#endif /* defined(TARGET_I386) */
1457

    
1458
/* this stack is the equivalent of the kernel stack associated with a
1459
   thread/process */
1460
#define NEW_STACK_SIZE 8192
1461

    
1462
static int clone_func(void *arg)
1463
{
1464
    CPUState *env = arg;
1465
    cpu_loop(env);
1466
    /* never exits */
1467
    return 0;
1468
}
1469

    
1470
int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
1471
{
1472
    int ret;
1473
    TaskState *ts;
1474
    uint8_t *new_stack;
1475
    CPUState *new_env;
1476
    
1477
    if (flags & CLONE_VM) {
1478
        ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
1479
        memset(ts, 0, sizeof(TaskState));
1480
        new_stack = ts->stack;
1481
        ts->used = 1;
1482
        /* add in task state list */
1483
        ts->next = first_task_state;
1484
        first_task_state = ts;
1485
        /* we create a new CPU instance. */
1486
        new_env = cpu_init();
1487
        memcpy(new_env, env, sizeof(CPUState));
1488
#if defined(TARGET_I386)
1489
        if (!newsp)
1490
            newsp = env->regs[R_ESP];
1491
        new_env->regs[R_ESP] = newsp;
1492
        new_env->regs[R_EAX] = 0;
1493
#elif defined(TARGET_ARM)
1494
        if (!newsp)
1495
            newsp = env->regs[13];
1496
        new_env->regs[13] = newsp;
1497
        new_env->regs[0] = 0;
1498
#elif defined(TARGET_SPARC)
1499
        printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1500
#elif defined(TARGET_PPC)
1501
        if (!newsp)
1502
            newsp = env->gpr[1];
1503
        new_env->gpr[1] = newsp;
1504
        { 
1505
            int i;
1506
            for (i = 7; i < 32; i++)
1507
                new_env->gpr[i] = 0;
1508
        }
1509
#else
1510
#error unsupported target CPU
1511
#endif
1512
        new_env->opaque = ts;
1513
#ifdef __ia64__
1514
        ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1515
#else
1516
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1517
#endif
1518
    } else {
1519
        /* if no CLONE_VM, we consider it is a fork */
1520
        if ((flags & ~CSIGNAL) != 0)
1521
            return -EINVAL;
1522
        ret = fork();
1523
    }
1524
    return ret;
1525
}
1526

    
1527
static long do_fcntl(int fd, int cmd, unsigned long arg)
1528
{
1529
    struct flock fl;
1530
    struct target_flock *target_fl = (void *)arg;
1531
    long ret;
1532
    
1533
    switch(cmd) {
1534
    case TARGET_F_GETLK:
1535
        ret = fcntl(fd, cmd, &fl);
1536
        if (ret == 0) {
1537
            target_fl->l_type = tswap16(fl.l_type);
1538
            target_fl->l_whence = tswap16(fl.l_whence);
1539
            target_fl->l_start = tswapl(fl.l_start);
1540
            target_fl->l_len = tswapl(fl.l_len);
1541
            target_fl->l_pid = tswapl(fl.l_pid);
1542
        }
1543
        break;
1544
        
1545
    case TARGET_F_SETLK:
1546
    case TARGET_F_SETLKW:
1547
        fl.l_type = tswap16(target_fl->l_type);
1548
        fl.l_whence = tswap16(target_fl->l_whence);
1549
        fl.l_start = tswapl(target_fl->l_start);
1550
        fl.l_len = tswapl(target_fl->l_len);
1551
        fl.l_pid = tswapl(target_fl->l_pid);
1552
        ret = fcntl(fd, cmd, &fl);
1553
        break;
1554
        
1555
    case TARGET_F_GETLK64:
1556
    case TARGET_F_SETLK64:
1557
    case TARGET_F_SETLKW64:
1558
        ret = -1;
1559
        errno = EINVAL;
1560
        break;
1561

    
1562
    case F_GETFL:
1563
        ret = fcntl(fd, cmd, arg);
1564
        ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
1565
        break;
1566

    
1567
    case F_SETFL:
1568
        ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl));
1569
        break;
1570

    
1571
    default:
1572
        ret = fcntl(fd, cmd, arg);
1573
        break;
1574
    }
1575
    return ret;
1576
}
1577

    
1578
#ifdef USE_UID16
1579

    
1580
static inline int high2lowuid(int uid)
1581
{
1582
    if (uid > 65535)
1583
        return 65534;
1584
    else
1585
        return uid;
1586
}
1587

    
1588
static inline int high2lowgid(int gid)
1589
{
1590
    if (gid > 65535)
1591
        return 65534;
1592
    else
1593
        return gid;
1594
}
1595

    
1596
static inline int low2highuid(int uid)
1597
{
1598
    if ((int16_t)uid == -1)
1599
        return -1;
1600
    else
1601
        return uid;
1602
}
1603

    
1604
static inline int low2highgid(int gid)
1605
{
1606
    if ((int16_t)gid == -1)
1607
        return -1;
1608
    else
1609
        return gid;
1610
}
1611

    
1612
#endif /* USE_UID16 */
1613

    
1614
void syscall_init(void)
1615
{
1616
    IOCTLEntry *ie;
1617
    const argtype *arg_type;
1618
    int size;
1619

    
1620
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
1621
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 
1622
#include "syscall_types.h"
1623
#undef STRUCT
1624
#undef STRUCT_SPECIAL
1625

    
1626
    /* we patch the ioctl size if necessary. We rely on the fact that
1627
       no ioctl has all the bits at '1' in the size field */
1628
    ie = ioctl_entries;
1629
    while (ie->target_cmd != 0) {
1630
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
1631
            TARGET_IOC_SIZEMASK) {
1632
            arg_type = ie->arg_type;
1633
            if (arg_type[0] != TYPE_PTR) {
1634
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n", 
1635
                        ie->target_cmd);
1636
                exit(1);
1637
            }
1638
            arg_type++;
1639
            size = thunk_type_size(arg_type, 0);
1640
            ie->target_cmd = (ie->target_cmd & 
1641
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
1642
                (size << TARGET_IOC_SIZESHIFT);
1643
        }
1644
        /* automatic consistency check if same arch */
1645
#if defined(__i386__) && defined(TARGET_I386)
1646
        if (ie->target_cmd != ie->host_cmd) {
1647
            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n", 
1648
                    ie->target_cmd, ie->host_cmd);
1649
        }
1650
#endif
1651
        ie++;
1652
    }
1653
}
1654

    
1655
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 
1656
                long arg4, long arg5, long arg6)
1657
{
1658
    long ret;
1659
    struct stat st;
1660
    struct kernel_statfs *stfs;
1661
    
1662
#ifdef DEBUG
1663
    gemu_log("syscall %d", num);
1664
#endif
1665
    switch(num) {
1666
    case TARGET_NR_exit:
1667
#ifdef HAVE_GPROF
1668
        _mcleanup();
1669
#endif
1670
        gdb_exit(cpu_env, arg1);
1671
        /* XXX: should free thread stack and CPU env */
1672
        _exit(arg1);
1673
        ret = 0; /* avoid warning */
1674
        break;
1675
    case TARGET_NR_read:
1676
        page_unprotect_range((void *)arg2, arg3);
1677
        ret = get_errno(read(arg1, (void *)arg2, arg3));
1678
        break;
1679
    case TARGET_NR_write:
1680
        ret = get_errno(write(arg1, (void *)arg2, arg3));
1681
        break;
1682
    case TARGET_NR_open:
1683
        ret = get_errno(open(path((const char *)arg1),
1684
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
1685
                             arg3));
1686
        break;
1687
    case TARGET_NR_close:
1688
        ret = get_errno(close(arg1));
1689
        break;
1690
    case TARGET_NR_brk:
1691
        ret = do_brk((char *)arg1);
1692
        break;
1693
    case TARGET_NR_fork:
1694
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
1695
        break;
1696
    case TARGET_NR_waitpid:
1697
        {
1698
            int *status = (int *)arg2;
1699
            ret = get_errno(waitpid(arg1, status, arg3));
1700
            if (!is_error(ret) && status)
1701
                tswapls((long *)&status);
1702
        }
1703
        break;
1704
    case TARGET_NR_creat:
1705
        ret = get_errno(creat((const char *)arg1, arg2));
1706
        break;
1707
    case TARGET_NR_link:
1708
        ret = get_errno(link((const char *)arg1, (const char *)arg2));
1709
        break;
1710
    case TARGET_NR_unlink:
1711
        ret = get_errno(unlink((const char *)arg1));
1712
        break;
1713
    case TARGET_NR_execve:
1714
        {
1715
            char **argp, **envp;
1716
            int argc, envc;
1717
            uint32_t *p;
1718
            char **q;
1719

    
1720
            argc = 0;
1721
            for (p = (void *)arg2; *p; p++)
1722
                argc++;
1723
            envc = 0;
1724
            for (p = (void *)arg3; *p; p++)
1725
                envc++;
1726

    
1727
            argp = alloca((argc + 1) * sizeof(void *));
1728
            envp = alloca((envc + 1) * sizeof(void *));
1729

    
1730
            for (p = (void *)arg2, q = argp; *p; p++, q++)
1731
                *q = (void *)tswap32(*p);
1732
            *q = NULL;
1733

    
1734
            for (p = (void *)arg3, q = envp; *p; p++, q++)
1735
                *q = (void *)tswap32(*p);
1736
            *q = NULL;
1737

    
1738
            ret = get_errno(execve((const char *)arg1, argp, envp));
1739
        }
1740
        break;
1741
    case TARGET_NR_chdir:
1742
        ret = get_errno(chdir((const char *)arg1));
1743
        break;
1744
#ifdef TARGET_NR_time
1745
    case TARGET_NR_time:
1746
        {
1747
            int *time_ptr = (int *)arg1;
1748
            ret = get_errno(time((time_t *)time_ptr));
1749
            if (!is_error(ret) && time_ptr)
1750
                tswap32s(time_ptr);
1751
        }
1752
        break;
1753
#endif
1754
    case TARGET_NR_mknod:
1755
        ret = get_errno(mknod((const char *)arg1, arg2, arg3));
1756
        break;
1757
    case TARGET_NR_chmod:
1758
        ret = get_errno(chmod((const char *)arg1, arg2));
1759
        break;
1760
#ifdef TARGET_NR_break
1761
    case TARGET_NR_break:
1762
        goto unimplemented;
1763
#endif
1764
#ifdef TARGET_NR_oldstat
1765
    case TARGET_NR_oldstat:
1766
        goto unimplemented;
1767
#endif
1768
    case TARGET_NR_lseek:
1769
        ret = get_errno(lseek(arg1, arg2, arg3));
1770
        break;
1771
    case TARGET_NR_getpid:
1772
        ret = get_errno(getpid());
1773
        break;
1774
    case TARGET_NR_mount:
1775
        /* need to look at the data field */
1776
        goto unimplemented;
1777
    case TARGET_NR_umount:
1778
        ret = get_errno(umount((const char *)arg1));
1779
        break;
1780
    case TARGET_NR_stime:
1781
        {
1782
            int *time_ptr = (int *)arg1;
1783
            if (time_ptr)
1784
                tswap32s(time_ptr);
1785
            ret = get_errno(stime((time_t *)time_ptr));
1786
        }
1787
        break;
1788
    case TARGET_NR_ptrace:
1789
        goto unimplemented;
1790
    case TARGET_NR_alarm:
1791
        ret = alarm(arg1);
1792
        break;
1793
#ifdef TARGET_NR_oldfstat
1794
    case TARGET_NR_oldfstat:
1795
        goto unimplemented;
1796
#endif
1797
    case TARGET_NR_pause:
1798
        ret = get_errno(pause());
1799
        break;
1800
    case TARGET_NR_utime:
1801
        {
1802
            struct utimbuf tbuf, *tbuf1;
1803
            struct target_utimbuf *target_tbuf = (void *)arg2;
1804
            if (target_tbuf) {
1805
                get_user(tbuf.actime, &target_tbuf->actime);
1806
                get_user(tbuf.modtime, &target_tbuf->modtime);
1807
                tbuf1 = &tbuf;
1808
            } else {
1809
                tbuf1 = NULL;
1810
            }
1811
            ret = get_errno(utime((const char *)arg1, tbuf1));
1812
        }
1813
        break;
1814
    case TARGET_NR_utimes:
1815
        {
1816
            struct target_timeval *target_tvp = (struct target_timeval *)arg2;
1817
            struct timeval *tvp, tv[2];
1818
            if (target_tvp) {
1819
                target_to_host_timeval(&tv[0], &target_tvp[0]);
1820
                target_to_host_timeval(&tv[1], &target_tvp[1]);
1821
                tvp = tv;
1822
            } else {
1823
                tvp = NULL;
1824
            }
1825
            ret = get_errno(utimes((const char *)arg1, tvp));
1826
        }
1827
        break;
1828
#ifdef TARGET_NR_stty
1829
    case TARGET_NR_stty:
1830
        goto unimplemented;
1831
#endif
1832
#ifdef TARGET_NR_gtty
1833
    case TARGET_NR_gtty:
1834
        goto unimplemented;
1835
#endif
1836
    case TARGET_NR_access:
1837
        ret = get_errno(access((const char *)arg1, arg2));
1838
        break;
1839
    case TARGET_NR_nice:
1840
        ret = get_errno(nice(arg1));
1841
        break;
1842
#ifdef TARGET_NR_ftime
1843
    case TARGET_NR_ftime:
1844
        goto unimplemented;
1845
#endif
1846
    case TARGET_NR_sync:
1847
        sync();
1848
        ret = 0;
1849
        break;
1850
    case TARGET_NR_kill:
1851
        ret = get_errno(kill(arg1, arg2));
1852
        break;
1853
    case TARGET_NR_rename:
1854
        ret = get_errno(rename((const char *)arg1, (const char *)arg2));
1855
        break;
1856
    case TARGET_NR_mkdir:
1857
        ret = get_errno(mkdir((const char *)arg1, arg2));
1858
        break;
1859
    case TARGET_NR_rmdir:
1860
        ret = get_errno(rmdir((const char *)arg1));
1861
        break;
1862
    case TARGET_NR_dup:
1863
        ret = get_errno(dup(arg1));
1864
        break;
1865
    case TARGET_NR_pipe:
1866
        {
1867
            int *pipe_ptr = (int *)arg1;
1868
            ret = get_errno(pipe(pipe_ptr));
1869
            if (!is_error(ret)) {
1870
                tswap32s(&pipe_ptr[0]);
1871
                tswap32s(&pipe_ptr[1]);
1872
            }
1873
        }
1874
        break;
1875
    case TARGET_NR_times:
1876
        {
1877
            struct target_tms *tmsp = (void *)arg1;
1878
            struct tms tms;
1879
            ret = get_errno(times(&tms));
1880
            if (tmsp) {
1881
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
1882
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
1883
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
1884
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
1885
            }
1886
            if (!is_error(ret))
1887
                ret = host_to_target_clock_t(ret);
1888
        }
1889
        break;
1890
#ifdef TARGET_NR_prof
1891
    case TARGET_NR_prof:
1892
        goto unimplemented;
1893
#endif
1894
    case TARGET_NR_signal:
1895
        goto unimplemented;
1896

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

    
2332
            if (target_value) {
2333
                pvalue = &value;
2334
                target_to_host_timeval(&pvalue->it_interval, 
2335
                                       &target_value->it_interval);
2336
                target_to_host_timeval(&pvalue->it_value, 
2337
                                       &target_value->it_value);
2338
            } else {
2339
                pvalue = NULL;
2340
            }
2341
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
2342
            if (!is_error(ret) && target_ovalue) {
2343
                host_to_target_timeval(&target_ovalue->it_interval, 
2344
                                       &ovalue.it_interval);
2345
                host_to_target_timeval(&target_ovalue->it_value, 
2346
                                       &ovalue.it_value);
2347
            }
2348
        }
2349
        break;
2350
    case TARGET_NR_getitimer:
2351
        {
2352
            struct target_itimerval *target_value = (void *)arg2;
2353
            struct itimerval value;
2354
            
2355
            ret = get_errno(getitimer(arg1, &value));
2356
            if (!is_error(ret) && target_value) {
2357
                host_to_target_timeval(&target_value->it_interval, 
2358
                                       &value.it_interval);
2359
                host_to_target_timeval(&target_value->it_value, 
2360
                                       &value.it_value);
2361
            }
2362
        }
2363
        break;
2364
    case TARGET_NR_stat:
2365
        ret = get_errno(stat(path((const char *)arg1), &st));
2366
        goto do_stat;
2367
    case TARGET_NR_lstat:
2368
        ret = get_errno(lstat(path((const char *)arg1), &st));
2369
        goto do_stat;
2370
    case TARGET_NR_fstat:
2371
        {
2372
            ret = get_errno(fstat(arg1, &st));
2373
        do_stat:
2374
            if (!is_error(ret)) {
2375
                struct target_stat *target_st = (void *)arg2;
2376
                target_st->st_dev = tswap16(st.st_dev);
2377
                target_st->st_ino = tswapl(st.st_ino);
2378
#if defined(TARGET_PPC)
2379
                target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
2380
                target_st->st_uid = tswap32(st.st_uid);
2381
                target_st->st_gid = tswap32(st.st_gid);
2382
#else
2383
                target_st->st_mode = tswap16(st.st_mode);
2384
                target_st->st_uid = tswap16(st.st_uid);
2385
                target_st->st_gid = tswap16(st.st_gid);
2386
#endif
2387
                target_st->st_nlink = tswap16(st.st_nlink);
2388
                target_st->st_rdev = tswap16(st.st_rdev);
2389
                target_st->st_size = tswapl(st.st_size);
2390
                target_st->st_blksize = tswapl(st.st_blksize);
2391
                target_st->st_blocks = tswapl(st.st_blocks);
2392
                target_st->target_st_atime = tswapl(st.st_atime);
2393
                target_st->target_st_mtime = tswapl(st.st_mtime);
2394
                target_st->target_st_ctime = tswapl(st.st_ctime);
2395
            }
2396
        }
2397
        break;
2398
#ifdef TARGET_NR_olduname
2399
    case TARGET_NR_olduname:
2400
        goto unimplemented;
2401
#endif
2402
#ifdef TARGET_NR_iopl
2403
    case TARGET_NR_iopl:
2404
        goto unimplemented;
2405
#endif
2406
    case TARGET_NR_vhangup:
2407
        ret = get_errno(vhangup());
2408
        break;
2409
#ifdef TARGET_NR_idle
2410
    case TARGET_NR_idle:
2411
        goto unimplemented;
2412
#endif
2413
#ifdef TARGET_NR_syscall
2414
    case TARGET_NR_syscall:
2415
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
2416
            break;
2417
#endif
2418
    case TARGET_NR_wait4:
2419
        {
2420
            int status;
2421
            target_long *status_ptr = (void *)arg2;
2422
            struct rusage rusage, *rusage_ptr;
2423
            struct target_rusage *target_rusage = (void *)arg4;
2424
            if (target_rusage)
2425
                rusage_ptr = &rusage;
2426
            else
2427
                rusage_ptr = NULL;
2428
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
2429
            if (!is_error(ret)) {
2430
                if (status_ptr)
2431
                    *status_ptr = tswap32(status);
2432
                if (target_rusage) {
2433
                    host_to_target_rusage(target_rusage, &rusage);
2434
                }
2435
            }
2436
        }
2437
        break;
2438
    case TARGET_NR_swapoff:
2439
        ret = get_errno(swapoff((const char *)arg1));
2440
        break;
2441
    case TARGET_NR_sysinfo:
2442
        {
2443
            struct target_sysinfo *target_value = (void *)arg1;
2444
            struct sysinfo value;
2445
            ret = get_errno(sysinfo(&value));
2446
            if (!is_error(ret) && target_value)
2447
            {
2448
                __put_user(value.uptime, &target_value->uptime);
2449
                __put_user(value.loads[0], &target_value->loads[0]);
2450
                __put_user(value.loads[1], &target_value->loads[1]);
2451
                __put_user(value.loads[2], &target_value->loads[2]);
2452
                __put_user(value.totalram, &target_value->totalram);
2453
                __put_user(value.freeram, &target_value->freeram);
2454
                __put_user(value.sharedram, &target_value->sharedram);
2455
                __put_user(value.bufferram, &target_value->bufferram);
2456
                __put_user(value.totalswap, &target_value->totalswap);
2457
                __put_user(value.freeswap, &target_value->freeswap);
2458
                __put_user(value.procs, &target_value->procs);
2459
                __put_user(value.totalhigh, &target_value->totalhigh);
2460
                __put_user(value.freehigh, &target_value->freehigh);
2461
                __put_user(value.mem_unit, &target_value->mem_unit);
2462
            }
2463
        }
2464
        break;
2465
    case TARGET_NR_ipc:
2466
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
2467
        break;
2468
    case TARGET_NR_fsync:
2469
        ret = get_errno(fsync(arg1));
2470
        break;
2471
    case TARGET_NR_clone:
2472
        ret = get_errno(do_fork(cpu_env, arg1, arg2));
2473
        break;
2474
#ifdef __NR_exit_group
2475
        /* new thread calls */
2476
    case TARGET_NR_exit_group:
2477
        gdb_exit(cpu_env, arg1);
2478
        ret = get_errno(exit_group(arg1));
2479
        break;
2480
#endif
2481
    case TARGET_NR_setdomainname:
2482
        ret = get_errno(setdomainname((const char *)arg1, arg2));
2483
        break;
2484
    case TARGET_NR_uname:
2485
        /* no need to transcode because we use the linux syscall */
2486
        {
2487
            struct new_utsname * buf;
2488
    
2489
            buf = (struct new_utsname *)arg1;
2490
            ret = get_errno(sys_uname(buf));
2491
            if (!is_error(ret)) {
2492
                /* Overrite the native machine name with whatever is being
2493
                   emulated. */
2494
                strcpy (buf->machine, UNAME_MACHINE);
2495
            }
2496
        }
2497
        break;
2498
#ifdef TARGET_I386
2499
    case TARGET_NR_modify_ldt:
2500
        ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
2501
        break;
2502
    case TARGET_NR_vm86old:
2503
        goto unimplemented;
2504
    case TARGET_NR_vm86:
2505
        ret = do_vm86(cpu_env, arg1, (void *)arg2);
2506
        break;
2507
#endif
2508
    case TARGET_NR_adjtimex:
2509
        goto unimplemented;
2510
    case TARGET_NR_create_module:
2511
    case TARGET_NR_init_module:
2512
    case TARGET_NR_delete_module:
2513
    case TARGET_NR_get_kernel_syms:
2514
        goto unimplemented;
2515
    case TARGET_NR_quotactl:
2516
        goto unimplemented;
2517
    case TARGET_NR_getpgid:
2518
        ret = get_errno(getpgid(arg1));
2519
        break;
2520
    case TARGET_NR_fchdir:
2521
        ret = get_errno(fchdir(arg1));
2522
        break;
2523
    case TARGET_NR_bdflush:
2524
        goto unimplemented;
2525
    case TARGET_NR_sysfs:
2526
        goto unimplemented;
2527
    case TARGET_NR_personality:
2528
        ret = get_errno(personality(arg1));
2529
        break;
2530
    case TARGET_NR_afs_syscall:
2531
        goto unimplemented;
2532
    case TARGET_NR__llseek:
2533
        {
2534
#if defined (__x86_64__)
2535
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
2536
            *(int64_t *)arg4 = ret;
2537
#else
2538
            int64_t res;
2539
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
2540
            *(int64_t *)arg4 = tswap64(res);
2541
#endif
2542
        }
2543
        break;
2544
    case TARGET_NR_getdents:
2545
#if TARGET_LONG_SIZE != 4
2546
#warning not supported
2547
#elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
2548
        {
2549
            struct target_dirent *target_dirp = (void *)arg2;
2550
            struct dirent *dirp;
2551
            long count = arg3;
2552

    
2553
            dirp = malloc(count);
2554
            if (!dirp)
2555
                return -ENOMEM;
2556
            
2557
            ret = get_errno(sys_getdents(arg1, dirp, count));
2558
            if (!is_error(ret)) {
2559
                struct dirent *de;
2560
                struct target_dirent *tde;
2561
                int len = ret;
2562
                int reclen, treclen;
2563
                int count1, tnamelen;
2564

    
2565
                count1 = 0;
2566
                de = dirp;
2567
                tde = target_dirp;
2568
                while (len > 0) {
2569
                    reclen = de->d_reclen;
2570
                    treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
2571
                    tde->d_reclen = tswap16(treclen);
2572
                    tde->d_ino = tswapl(de->d_ino);
2573
                    tde->d_off = tswapl(de->d_off);
2574
                    tnamelen = treclen - (2 * sizeof(target_long) + 2);
2575
                    if (tnamelen > 256)
2576
                        tnamelen = 256;
2577
                    /* XXX: may not be correct */
2578
                    strncpy(tde->d_name, de->d_name, tnamelen);
2579
                    de = (struct dirent *)((char *)de + reclen);
2580
                    len -= reclen;
2581
                    tde = (struct dirent *)((char *)tde + treclen);
2582
                    count1 += treclen;
2583
                }
2584
                ret = count1;
2585
            }
2586
            free(dirp);
2587
        }
2588
#else
2589
        {
2590
            struct dirent *dirp = (void *)arg2;
2591
            long count = arg3;
2592

    
2593
            ret = get_errno(sys_getdents(arg1, dirp, count));
2594
            if (!is_error(ret)) {
2595
                struct dirent *de;
2596
                int len = ret;
2597
                int reclen;
2598
                de = dirp;
2599
                while (len > 0) {
2600
                    reclen = de->d_reclen;
2601
                    if (reclen > len)
2602
                        break;
2603
                    de->d_reclen = tswap16(reclen);
2604
                    tswapls(&de->d_ino);
2605
                    tswapls(&de->d_off);
2606
                    de = (struct dirent *)((char *)de + reclen);
2607
                    len -= reclen;
2608
                }
2609
            }
2610
        }
2611
#endif
2612
        break;
2613
#ifdef TARGET_NR_getdents64
2614
    case TARGET_NR_getdents64:
2615
        {
2616
            struct dirent64 *dirp = (void *)arg2;
2617
            long count = arg3;
2618
            ret = get_errno(sys_getdents64(arg1, dirp, count));
2619
            if (!is_error(ret)) {
2620
                struct dirent64 *de;
2621
                int len = ret;
2622
                int reclen;
2623
                de = dirp;
2624
                while (len > 0) {
2625
                    reclen = de->d_reclen;
2626
                    if (reclen > len)
2627
                        break;
2628
                    de->d_reclen = tswap16(reclen);
2629
                    tswap64s(&de->d_ino);
2630
                    tswap64s(&de->d_off);
2631
                    de = (struct dirent64 *)((char *)de + reclen);
2632
                    len -= reclen;
2633
                }
2634
            }
2635
        }
2636
        break;
2637
#endif /* TARGET_NR_getdents64 */
2638
    case TARGET_NR__newselect:
2639
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
2640
                        (void *)arg5);
2641
        break;
2642
    case TARGET_NR_poll:
2643
        {
2644
            struct target_pollfd *target_pfd = (void *)arg1;
2645
            unsigned int nfds = arg2;
2646
            int timeout = arg3;
2647
            struct pollfd *pfd;
2648
            unsigned int i;
2649

    
2650
            pfd = alloca(sizeof(struct pollfd) * nfds);
2651
            for(i = 0; i < nfds; i++) {
2652
                pfd[i].fd = tswap32(target_pfd[i].fd);
2653
                pfd[i].events = tswap16(target_pfd[i].events);
2654
            }
2655
            ret = get_errno(poll(pfd, nfds, timeout));
2656
            if (!is_error(ret)) {
2657
                for(i = 0; i < nfds; i++) {
2658
                    target_pfd[i].revents = tswap16(pfd[i].revents);
2659
                }
2660
            }
2661
        }
2662
        break;
2663
    case TARGET_NR_flock:
2664
        /* NOTE: the flock constant seems to be the same for every
2665
           Linux platform */
2666
        ret = get_errno(flock(arg1, arg2));
2667
        break;
2668
    case TARGET_NR_readv:
2669
        {
2670
            int count = arg3;
2671
            int i;
2672
            struct iovec *vec;
2673
            struct target_iovec *target_vec = (void *)arg2;
2674

    
2675
            vec = alloca(count * sizeof(struct iovec));
2676
            for(i = 0;i < count; i++) {
2677
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2678
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
2679
            }
2680
            ret = get_errno(readv(arg1, vec, count));
2681
        }
2682
        break;
2683
    case TARGET_NR_writev:
2684
        {
2685
            int count = arg3;
2686
            int i;
2687
            struct iovec *vec;
2688
            struct target_iovec *target_vec = (void *)arg2;
2689

    
2690
            vec = alloca(count * sizeof(struct iovec));
2691
            for(i = 0;i < count; i++) {
2692
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2693
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
2694
            }
2695
            ret = get_errno(writev(arg1, vec, count));
2696
        }
2697
        break;
2698
    case TARGET_NR_getsid:
2699
        ret = get_errno(getsid(arg1));
2700
        break;
2701
    case TARGET_NR_fdatasync:
2702
        ret = get_errno(fdatasync(arg1));
2703
        break;
2704
    case TARGET_NR__sysctl:
2705
        /* We don't implement this, but ENODIR is always a safe
2706
           return value. */
2707
        return -ENOTDIR;
2708
    case TARGET_NR_sched_setparam:
2709
        {
2710
            struct sched_param *target_schp = (void *)arg2;
2711
            struct sched_param schp;
2712
            schp.sched_priority = tswap32(target_schp->sched_priority);
2713
            ret = get_errno(sched_setparam(arg1, &schp));
2714
        }
2715
        break;
2716
    case TARGET_NR_sched_getparam:
2717
        {
2718
            struct sched_param *target_schp = (void *)arg2;
2719
            struct sched_param schp;
2720
            ret = get_errno(sched_getparam(arg1, &schp));
2721
            if (!is_error(ret)) {
2722
                target_schp->sched_priority = tswap32(schp.sched_priority);
2723
            }
2724
        }
2725
        break;
2726
    case TARGET_NR_sched_setscheduler:
2727
        {
2728
            struct sched_param *target_schp = (void *)arg3;
2729
            struct sched_param schp;
2730
            schp.sched_priority = tswap32(target_schp->sched_priority);
2731
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
2732
        }
2733
        break;
2734
    case TARGET_NR_sched_getscheduler:
2735
        ret = get_errno(sched_getscheduler(arg1));
2736
        break;
2737
    case TARGET_NR_sched_yield:
2738
        ret = get_errno(sched_yield());
2739
        break;
2740
    case TARGET_NR_sched_get_priority_max:
2741
        ret = get_errno(sched_get_priority_max(arg1));
2742
        break;
2743
    case TARGET_NR_sched_get_priority_min:
2744
        ret = get_errno(sched_get_priority_min(arg1));
2745
        break;
2746
    case TARGET_NR_sched_rr_get_interval:
2747
        {
2748
            struct target_timespec *target_ts = (void *)arg2;
2749
            struct timespec ts;
2750
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
2751
            if (!is_error(ret)) {
2752
                target_ts->tv_sec = tswapl(ts.tv_sec);
2753
                target_ts->tv_nsec = tswapl(ts.tv_nsec);
2754
            }
2755
        }
2756
        break;
2757
    case TARGET_NR_nanosleep:
2758
        {
2759
            struct target_timespec *target_req = (void *)arg1;
2760
            struct target_timespec *target_rem = (void *)arg2;
2761
            struct timespec req, rem;
2762
            req.tv_sec = tswapl(target_req->tv_sec);
2763
            req.tv_nsec = tswapl(target_req->tv_nsec);
2764
            ret = get_errno(nanosleep(&req, &rem));
2765
            if (is_error(ret) && target_rem) {
2766
                target_rem->tv_sec = tswapl(rem.tv_sec);
2767
                target_rem->tv_nsec = tswapl(rem.tv_nsec);
2768
            }
2769
        }
2770
        break;
2771
    case TARGET_NR_query_module:
2772
        goto unimplemented;
2773
    case TARGET_NR_nfsservctl:
2774
        goto unimplemented;
2775
    case TARGET_NR_prctl:
2776
        goto unimplemented;
2777
#ifdef TARGET_NR_pread
2778
    case TARGET_NR_pread:
2779
        page_unprotect_range((void *)arg2, arg3);
2780
        ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4));
2781
        break;
2782
    case TARGET_NR_pwrite:
2783
        ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
2784
        break;
2785
#endif
2786
    case TARGET_NR_getcwd:
2787
        ret = get_errno(sys_getcwd1((char *)arg1, arg2));
2788
        break;
2789
    case TARGET_NR_capget:
2790
        goto unimplemented;
2791
    case TARGET_NR_capset:
2792
        goto unimplemented;
2793
    case TARGET_NR_sigaltstack:
2794
        goto unimplemented;
2795
    case TARGET_NR_sendfile:
2796
        goto unimplemented;
2797
#ifdef TARGET_NR_getpmsg
2798
    case TARGET_NR_getpmsg:
2799
        goto unimplemented;
2800
#endif
2801
#ifdef TARGET_NR_putpmsg
2802
    case TARGET_NR_putpmsg:
2803
        goto unimplemented;
2804
#endif
2805
    case TARGET_NR_vfork:
2806
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
2807
        break;
2808
#ifdef TARGET_NR_ugetrlimit
2809
    case TARGET_NR_ugetrlimit:
2810
    {
2811
        struct rlimit rlim;
2812
        ret = get_errno(getrlimit(arg1, &rlim));
2813
        if (!is_error(ret)) {
2814
            struct target_rlimit *target_rlim = (void *)arg2;
2815
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2816
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
2817
        }
2818
        break;
2819
    }
2820
#endif
2821
#ifdef TARGET_NR_truncate64
2822
    case TARGET_NR_truncate64:
2823
        ret = get_errno(truncate64((const char *)arg1, arg2));
2824
        break;
2825
#endif
2826
#ifdef TARGET_NR_ftruncate64
2827
    case TARGET_NR_ftruncate64:
2828
        ret = get_errno(ftruncate64(arg1, arg2));
2829
        break;
2830
#endif
2831
#ifdef TARGET_NR_stat64
2832
    case TARGET_NR_stat64:
2833
        ret = get_errno(stat(path((const char *)arg1), &st));
2834
        goto do_stat64;
2835
#endif
2836
#ifdef TARGET_NR_lstat64
2837
    case TARGET_NR_lstat64:
2838
        ret = get_errno(lstat(path((const char *)arg1), &st));
2839
        goto do_stat64;
2840
#endif
2841
#ifdef TARGET_NR_fstat64
2842
    case TARGET_NR_fstat64:
2843
        {
2844
            ret = get_errno(fstat(arg1, &st));
2845
        do_stat64:
2846
            if (!is_error(ret)) {
2847
                struct target_stat64 *target_st = (void *)arg2;
2848
                memset(target_st, 0, sizeof(struct target_stat64));
2849
                put_user(st.st_dev, &target_st->st_dev);
2850
                put_user(st.st_ino, &target_st->st_ino);
2851
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
2852
                put_user(st.st_ino, &target_st->__st_ino);
2853
#endif
2854
                put_user(st.st_mode, &target_st->st_mode);
2855
                put_user(st.st_nlink, &target_st->st_nlink);
2856
                put_user(st.st_uid, &target_st->st_uid);
2857
                put_user(st.st_gid, &target_st->st_gid);
2858
                put_user(st.st_rdev, &target_st->st_rdev);
2859
                /* XXX: better use of kernel struct */
2860
                put_user(st.st_size, &target_st->st_size);
2861
                put_user(st.st_blksize, &target_st->st_blksize);
2862
                put_user(st.st_blocks, &target_st->st_blocks);
2863
                put_user(st.st_atime, &target_st->target_st_atime);
2864
                put_user(st.st_mtime, &target_st->target_st_mtime);
2865
                put_user(st.st_ctime, &target_st->target_st_ctime);
2866
            }
2867
        }
2868
        break;
2869
#endif
2870
#ifdef USE_UID16
2871
    case TARGET_NR_lchown:
2872
        ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2873
        break;
2874
    case TARGET_NR_getuid:
2875
        ret = get_errno(high2lowuid(getuid()));
2876
        break;
2877
    case TARGET_NR_getgid:
2878
        ret = get_errno(high2lowgid(getgid()));
2879
        break;
2880
    case TARGET_NR_geteuid:
2881
        ret = get_errno(high2lowuid(geteuid()));
2882
        break;
2883
    case TARGET_NR_getegid:
2884
        ret = get_errno(high2lowgid(getegid()));
2885
        break;
2886
    case TARGET_NR_setreuid:
2887
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
2888
        break;
2889
    case TARGET_NR_setregid:
2890
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
2891
        break;
2892
    case TARGET_NR_getgroups:
2893
        {
2894
            int gidsetsize = arg1;
2895
            uint16_t *target_grouplist = (void *)arg2;
2896
            gid_t *grouplist;
2897
            int i;
2898

    
2899
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2900
            ret = get_errno(getgroups(gidsetsize, grouplist));
2901
            if (!is_error(ret)) {
2902
                for(i = 0;i < gidsetsize; i++)
2903
                    target_grouplist[i] = tswap16(grouplist[i]);
2904
            }
2905
        }
2906
        break;
2907
    case TARGET_NR_setgroups:
2908
        {
2909
            int gidsetsize = arg1;
2910
            uint16_t *target_grouplist = (void *)arg2;
2911
            gid_t *grouplist;
2912
            int i;
2913

    
2914
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2915
            for(i = 0;i < gidsetsize; i++)
2916
                grouplist[i] = tswap16(target_grouplist[i]);
2917
            ret = get_errno(setgroups(gidsetsize, grouplist));
2918
        }
2919
        break;
2920
    case TARGET_NR_fchown:
2921
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
2922
        break;
2923
#ifdef TARGET_NR_setresuid
2924
    case TARGET_NR_setresuid:
2925
        ret = get_errno(setresuid(low2highuid(arg1), 
2926
                                  low2highuid(arg2), 
2927
                                  low2highuid(arg3)));
2928
        break;
2929
#endif
2930
#ifdef TARGET_NR_getresuid
2931
    case TARGET_NR_getresuid:
2932
        {
2933
            int ruid, euid, suid;
2934
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2935
            if (!is_error(ret)) {
2936
                *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
2937
                *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
2938
                *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
2939
            }
2940
        }
2941
        break;
2942
#endif
2943
#ifdef TARGET_NR_getresgid
2944
    case TARGET_NR_setresgid:
2945
        ret = get_errno(setresgid(low2highgid(arg1), 
2946
                                  low2highgid(arg2), 
2947
                                  low2highgid(arg3)));
2948
        break;
2949
#endif
2950
#ifdef TARGET_NR_getresgid
2951
    case TARGET_NR_getresgid:
2952
        {
2953
            int rgid, egid, sgid;
2954
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
2955
            if (!is_error(ret)) {
2956
                *(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
2957
                *(uint16_t *)arg2 = tswap16(high2lowgid(egid));
2958
                *(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
2959
            }
2960
        }
2961
        break;
2962
#endif
2963
    case TARGET_NR_chown:
2964
        ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2965
        break;
2966
    case TARGET_NR_setuid:
2967
        ret = get_errno(setuid(low2highuid(arg1)));
2968
        break;
2969
    case TARGET_NR_setgid:
2970
        ret = get_errno(setgid(low2highgid(arg1)));
2971
        break;
2972
    case TARGET_NR_setfsuid:
2973
        ret = get_errno(setfsuid(arg1));
2974
        break;
2975
    case TARGET_NR_setfsgid:
2976
        ret = get_errno(setfsgid(arg1));
2977
        break;
2978
#endif /* USE_UID16 */
2979

    
2980
#ifdef TARGET_NR_lchown32
2981
    case TARGET_NR_lchown32:
2982
        ret = get_errno(lchown((const char *)arg1, arg2, arg3));
2983
        break;
2984
#endif
2985
#ifdef TARGET_NR_getuid32
2986
    case TARGET_NR_getuid32:
2987
        ret = get_errno(getuid());
2988
        break;
2989
#endif
2990
#ifdef TARGET_NR_getgid32
2991
    case TARGET_NR_getgid32:
2992
        ret = get_errno(getgid());
2993
        break;
2994
#endif
2995
#ifdef TARGET_NR_geteuid32
2996
    case TARGET_NR_geteuid32:
2997
        ret = get_errno(geteuid());
2998
        break;
2999
#endif
3000
#ifdef TARGET_NR_getegid32
3001
    case TARGET_NR_getegid32:
3002
        ret = get_errno(getegid());
3003
        break;
3004
#endif
3005
#ifdef TARGET_NR_setreuid32
3006
    case TARGET_NR_setreuid32:
3007
        ret = get_errno(setreuid(arg1, arg2));
3008
        break;
3009
#endif
3010
#ifdef TARGET_NR_setregid32
3011
    case TARGET_NR_setregid32:
3012
        ret = get_errno(setregid(arg1, arg2));
3013
        break;
3014
#endif
3015
#ifdef TARGET_NR_getgroups32
3016
    case TARGET_NR_getgroups32:
3017
        {
3018
            int gidsetsize = arg1;
3019
            uint32_t *target_grouplist = (void *)arg2;
3020
            gid_t *grouplist;
3021
            int i;
3022

    
3023
            grouplist = alloca(gidsetsize * sizeof(gid_t));
3024
            ret = get_errno(getgroups(gidsetsize, grouplist));
3025
            if (!is_error(ret)) {
3026
                for(i = 0;i < gidsetsize; i++)
3027
                    put_user(grouplist[i], &target_grouplist[i]);
3028
            }
3029
        }
3030
        break;
3031
#endif
3032
#ifdef TARGET_NR_setgroups32
3033
    case TARGET_NR_setgroups32:
3034
        {
3035
            int gidsetsize = arg1;
3036
            uint32_t *target_grouplist = (void *)arg2;
3037
            gid_t *grouplist;
3038
            int i;
3039
            
3040
            grouplist = alloca(gidsetsize * sizeof(gid_t));
3041
            for(i = 0;i < gidsetsize; i++)
3042
                get_user(grouplist[i], &target_grouplist[i]);
3043
            ret = get_errno(setgroups(gidsetsize, grouplist));
3044
        }
3045
        break;
3046
#endif
3047
#ifdef TARGET_NR_fchown32
3048
    case TARGET_NR_fchown32:
3049
        ret = get_errno(fchown(arg1, arg2, arg3));
3050
        break;
3051
#endif
3052
#ifdef TARGET_NR_setresuid32
3053
    case TARGET_NR_setresuid32:
3054
        ret = get_errno(setresuid(arg1, arg2, arg3));
3055
        break;
3056
#endif
3057
#ifdef TARGET_NR_getresuid32
3058
    case TARGET_NR_getresuid32:
3059
        {
3060
            int ruid, euid, suid;
3061
            ret = get_errno(getresuid(&ruid, &euid, &suid));
3062
            if (!is_error(ret)) {
3063
                *(uint32_t *)arg1 = tswap32(ruid);
3064
                *(uint32_t *)arg2 = tswap32(euid);
3065
                *(uint32_t *)arg3 = tswap32(suid);
3066
            }
3067
        }
3068
        break;
3069
#endif
3070
#ifdef TARGET_NR_setresgid32
3071
    case TARGET_NR_setresgid32:
3072
        ret = get_errno(setresgid(arg1, arg2, arg3));
3073
        break;
3074
#endif
3075
#ifdef TARGET_NR_getresgid32
3076
    case TARGET_NR_getresgid32:
3077
        {
3078
            int rgid, egid, sgid;
3079
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
3080
            if (!is_error(ret)) {
3081
                *(uint32_t *)arg1 = tswap32(rgid);
3082
                *(uint32_t *)arg2 = tswap32(egid);
3083
                *(uint32_t *)arg3 = tswap32(sgid);
3084
            }
3085
        }
3086
        break;
3087
#endif
3088
#ifdef TARGET_NR_chown32
3089
    case TARGET_NR_chown32:
3090
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
3091
        break;
3092
#endif
3093
#ifdef TARGET_NR_setuid32
3094
    case TARGET_NR_setuid32:
3095
        ret = get_errno(setuid(arg1));
3096
        break;
3097
#endif
3098
#ifdef TARGET_NR_setgid32
3099
    case TARGET_NR_setgid32:
3100
        ret = get_errno(setgid(arg1));
3101
        break;
3102
#endif
3103
#ifdef TARGET_NR_setfsuid32
3104
    case TARGET_NR_setfsuid32:
3105
        ret = get_errno(setfsuid(arg1));
3106
        break;
3107
#endif
3108
#ifdef TARGET_NR_setfsgid32
3109
    case TARGET_NR_setfsgid32:
3110
        ret = get_errno(setfsgid(arg1));
3111
        break;
3112
#endif
3113

    
3114
    case TARGET_NR_pivot_root:
3115
        goto unimplemented;
3116
#ifdef TARGET_NR_mincore
3117
    case TARGET_NR_mincore:
3118
        goto unimplemented;
3119
#endif
3120
#ifdef TARGET_NR_madvise
3121
    case TARGET_NR_madvise:
3122
        goto unimplemented;
3123
#endif
3124
#if TARGET_LONG_BITS == 32
3125
    case TARGET_NR_fcntl64:
3126
    {
3127
        struct flock64 fl;
3128
        struct target_flock64 *target_fl = (void *)arg3;
3129

    
3130
        switch(arg2) {
3131
        case F_GETLK64:
3132
            ret = get_errno(fcntl(arg1, arg2, &fl));
3133
            if (ret == 0) {
3134
                target_fl->l_type = tswap16(fl.l_type);
3135
                target_fl->l_whence = tswap16(fl.l_whence);
3136
                target_fl->l_start = tswap64(fl.l_start);
3137
                target_fl->l_len = tswap64(fl.l_len);
3138
                target_fl->l_pid = tswapl(fl.l_pid);
3139
            }
3140
            break;
3141

    
3142
        case F_SETLK64:
3143
        case F_SETLKW64:
3144
            fl.l_type = tswap16(target_fl->l_type);
3145
            fl.l_whence = tswap16(target_fl->l_whence);
3146
            fl.l_start = tswap64(target_fl->l_start);
3147
            fl.l_len = tswap64(target_fl->l_len);
3148
            fl.l_pid = tswapl(target_fl->l_pid);
3149
            ret = get_errno(fcntl(arg1, arg2, &fl));
3150
            break;
3151
        default:
3152
            ret = get_errno(do_fcntl(arg1, arg2, arg3));
3153
            break;
3154
        }
3155
        break;
3156
    }
3157
#endif
3158
#ifdef TARGET_NR_security
3159
    case TARGET_NR_security:
3160
        goto unimplemented;
3161
#endif
3162
#ifdef TARGET_NR_getpagesize
3163
    case TARGET_NR_getpagesize:
3164
        ret = TARGET_PAGE_SIZE;
3165
        break;
3166
#endif
3167
    case TARGET_NR_gettid:
3168
        ret = get_errno(gettid());
3169
        break;
3170
    case TARGET_NR_readahead:
3171
        goto unimplemented;
3172
#ifdef TARGET_NR_setxattr
3173
    case TARGET_NR_setxattr:
3174
    case TARGET_NR_lsetxattr:
3175
    case TARGET_NR_fsetxattr:
3176
    case TARGET_NR_getxattr:
3177
    case TARGET_NR_lgetxattr:
3178
    case TARGET_NR_fgetxattr:
3179
    case TARGET_NR_listxattr:
3180
    case TARGET_NR_llistxattr:
3181
    case TARGET_NR_flistxattr:
3182
    case TARGET_NR_removexattr:
3183
    case TARGET_NR_lremovexattr:
3184
    case TARGET_NR_fremovexattr:
3185
        goto unimplemented_nowarn;
3186
#endif
3187
#ifdef TARGET_NR_set_thread_area
3188
    case TARGET_NR_set_thread_area:
3189
    case TARGET_NR_get_thread_area:
3190
        goto unimplemented_nowarn;
3191
#endif
3192
    default:
3193
    unimplemented:
3194
        gemu_log("qemu: Unsupported syscall: %d\n", num);
3195
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area)
3196
    unimplemented_nowarn:
3197
#endif
3198
        ret = -ENOSYS;
3199
        break;
3200
    }
3201
 fail:
3202
#ifdef DEBUG
3203
    gemu_log(" = %ld\n", ret);
3204
#endif
3205
    return ret;
3206
}
3207