Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 31e31b8a

History | View | Annotate | Download (42.1 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 <elf.h>
24
#include <endian.h>
25
#include <errno.h>
26
#include <unistd.h>
27
#include <fcntl.h>
28
#include <sys/types.h>
29
#include <sys/wait.h>
30
#include <sys/time.h>
31
#include <sys/stat.h>
32
#include <sys/mount.h>
33
#include <sys/resource.h>
34
#include <sys/mman.h>
35
#include <sys/swap.h>
36
#include <signal.h>
37
#include <sched.h>
38
#include <sys/socket.h>
39
#include <sys/uio.h>
40
#include <sys/user.h>
41

    
42
#define termios host_termios
43
#define winsize host_winsize
44
#define termio host_termio
45

    
46
#include <linux/termios.h>
47
#include <linux/unistd.h>
48
#include <linux/utsname.h>
49
#include <linux/cdrom.h>
50
#include <linux/hdreg.h>
51
#include <linux/soundcard.h>
52

    
53
#include "gemu.h"
54

    
55
#define DEBUG
56

    
57
#ifndef PAGE_SIZE
58
#define PAGE_SIZE 4096
59
#define PAGE_MASK ~(PAGE_SIZE - 1)
60
#endif
61

    
62
struct dirent {
63
        long            d_ino;
64
        long            d_off;
65
        unsigned short  d_reclen;
66
        char            d_name[256]; /* We must not include limits.h! */
67
};
68

    
69
#include "syscall_defs.h"
70

    
71
#ifdef TARGET_I386
72
#include "syscall-i386.h"
73
#endif
74

    
75
#define __NR_sys_uname __NR_uname
76
#define __NR_sys_getcwd __NR_getcwd
77
#define __NR_sys_statfs __NR_statfs
78
#define __NR_sys_fstatfs __NR_fstatfs
79

    
80
_syscall0(int, gettid)
81
_syscall1(int,sys_uname,struct new_utsname *,buf)
82
_syscall2(int,sys_getcwd,char *,buf,size_t,size)
83
_syscall3(int, getdents, uint, fd, struct dirent *, dirp, uint, count);
84
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
85
          loff_t *, res, uint, wh);
86
_syscall2(int,sys_statfs,const char *,path,struct statfs *,buf)
87
_syscall2(int,sys_fstatfs,int,fd,struct statfs *,buf)
88

    
89
static inline long get_errno(long ret)
90
{
91
    if (ret == -1)
92
        return -errno;
93
    else
94
        return ret;
95
}
96

    
97
static inline int is_error(long ret)
98
{
99
    return (unsigned long)ret >= (unsigned long)(-4096);
100
}
101

    
102
static char *target_brk;
103
static char *target_original_brk;
104

    
105
void target_set_brk(char *new_brk)
106
{
107
    target_brk = new_brk;
108
    target_original_brk = new_brk;
109
}
110

    
111
static long do_brk(char *new_brk)
112
{
113
    char *brk_page;
114
    long mapped_addr;
115
    int        new_alloc_size;
116

    
117
    if (!new_brk)
118
        return (long)target_brk;
119
    if (new_brk < target_original_brk)
120
        return -ENOMEM;
121
    
122
    brk_page = (char *)(((unsigned long)target_brk + PAGE_SIZE - 1) & PAGE_MASK);
123

    
124
    /* If the new brk is less than this, set it and we're done... */
125
    if (new_brk < brk_page) {
126
        target_brk = new_brk;
127
            return (long)target_brk;
128
    }
129

    
130
    /* We need to allocate more memory after the brk... */
131
    new_alloc_size = ((new_brk - brk_page + 1)+(PAGE_SIZE-1)) & PAGE_MASK;
132
    mapped_addr = get_errno((long)mmap((caddr_t)brk_page, new_alloc_size, 
133
                                       PROT_READ|PROT_WRITE,
134
                                       MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
135
    
136
    if (is_error(mapped_addr)) {
137
        return mapped_addr;
138
    } else {
139
        target_brk = new_brk;
140
            return (long)target_brk;
141
    }
142
}
143

    
144
static inline fd_set *target_to_host_fds(fd_set *fds, 
145
                                         target_long *target_fds, int n)
146
{
147
#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
148
    return (fd_set *)target_fds;
149
#else
150
    int i, b;
151
    if (target_fds) {
152
        FD_ZERO(fds);
153
        for(i = 0;i < n; i++) {
154
            b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
155
                 (i & (TARGET_LONG_BITS - 1))) & 1;
156
            if (b)
157
                FD_SET(i, fds);
158
        }
159
        return fds;
160
    } else {
161
        return NULL;
162
    }
163
#endif
164
}
165

    
166
static inline void host_to_target_fds(target_long *target_fds, 
167
                                      fd_set *fds, int n)
168
{
169
#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
170
    /* nothing to do */
171
#else
172
    int i, nw, j, k;
173
    target_long v;
174

    
175
    if (target_fds) {
176
        nw = n / TARGET_LONG_BITS;
177
        k = 0;
178
        for(i = 0;i < nw; i++) {
179
            v = 0;
180
            for(j = 0; j < TARGET_LONG_BITS; j++) {
181
                v |= ((FD_ISSET(k, fds) != 0) << j);
182
                k++;
183
            }
184
            target_fds[i] = tswapl(v);
185
        }
186
    }
187
#endif
188
}
189

    
190
/* XXX: incorrect for some archs */
191
static void host_to_target_old_sigset(target_ulong *old_sigset, 
192
                                      const sigset_t *sigset)
193
{
194
    *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
195
}
196

    
197
static void target_to_host_old_sigset(sigset_t *sigset, 
198
                                      const target_ulong *old_sigset)
199
{
200
    sigemptyset(sigset);
201
    *(unsigned long *)sigset = tswapl(*old_sigset);
202
}
203

    
204

    
205
static long do_select(long n, 
206
                      target_long *target_rfds, target_long *target_wfds, 
207
                      target_long *target_efds, struct target_timeval *target_tv)
208
{
209
    fd_set rfds, wfds, efds;
210
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
211
    struct timeval tv, *tv_ptr;
212
    long ret;
213

    
214
    rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
215
    wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
216
    efds_ptr = target_to_host_fds(&efds, target_efds, n);
217
            
218
    if (target_tv) {
219
        tv.tv_sec = tswapl(target_tv->tv_sec);
220
        tv.tv_usec = tswapl(target_tv->tv_usec);
221
        tv_ptr = &tv;
222
    } else {
223
        tv_ptr = NULL;
224
    }
225
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
226
    if (!is_error(ret)) {
227
        host_to_target_fds(target_rfds, rfds_ptr, n);
228
        host_to_target_fds(target_wfds, wfds_ptr, n);
229
        host_to_target_fds(target_efds, efds_ptr, n);
230

    
231
        if (target_tv) {
232
            target_tv->tv_sec = tswapl(tv.tv_sec);
233
            target_tv->tv_usec = tswapl(tv.tv_usec);
234
        }
235
    }
236
    return ret;
237
}
238

    
239
static long do_socketcall(int num, long *vptr)
240
{
241
    long ret;
242

    
243
    switch(num) {
244
    case SOCKOP_socket:
245
        ret = get_errno(socket(vptr[0], vptr[1], vptr[2]));
246
        break;
247
    case SOCKOP_bind:
248
        ret = get_errno(bind(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
249
        break;
250
    case SOCKOP_connect:
251
        ret = get_errno(connect(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
252
        break;
253
    case SOCKOP_listen:
254
        ret = get_errno(listen(vptr[0], vptr[1]));
255
        break;
256
    case SOCKOP_accept:
257
        {
258
            socklen_t size;
259
            size = tswap32(*(int32_t *)vptr[2]);
260
            ret = get_errno(accept(vptr[0], (struct sockaddr *)vptr[1], &size));
261
            if (!is_error(ret)) 
262
                *(int32_t *)vptr[2] = size;
263
        }
264
        break;
265
    case SOCKOP_getsockname:
266
        {
267
            socklen_t size;
268
            size = tswap32(*(int32_t *)vptr[2]);
269
            ret = get_errno(getsockname(vptr[0], (struct sockaddr *)vptr[1], &size));
270
            if (!is_error(ret)) 
271
                *(int32_t *)vptr[2] = size;
272
        }
273
        break;
274
    case SOCKOP_getpeername:
275
        {
276
            socklen_t size;
277
            size = tswap32(*(int32_t *)vptr[2]);
278
            ret = get_errno(getpeername(vptr[0], (struct sockaddr *)vptr[1], &size));
279
            if (!is_error(ret)) 
280
                *(int32_t *)vptr[2] = size;
281
        }
282
        break;
283
    case SOCKOP_socketpair:
284
        {
285
            int tab[2];
286
            int32_t *target_tab = (int32_t *)vptr[3];
287
            ret = get_errno(socketpair(vptr[0], vptr[1], vptr[2], tab));
288
            if (!is_error(ret)) {
289
                target_tab[0] = tswap32(tab[0]);
290
                target_tab[1] = tswap32(tab[1]);
291
            }
292
        }
293
        break;
294
    case SOCKOP_send:
295
        ret = get_errno(send(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
296
        break;
297
    case SOCKOP_recv:
298
        ret = get_errno(recv(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
299
        break;
300
    case SOCKOP_sendto:
301
        ret = get_errno(sendto(vptr[0], (void *)vptr[1], vptr[2], vptr[3], 
302
                               (struct sockaddr *)vptr[4], vptr[5]));
303
        break;
304
    case SOCKOP_recvfrom:
305
        {
306
            socklen_t size;
307
            size = tswap32(*(int32_t *)vptr[5]);
308
            ret = get_errno(recvfrom(vptr[0], (void *)vptr[1], vptr[2], 
309
                                     vptr[3], (struct sockaddr *)vptr[4], &size));
310
            if (!is_error(ret)) 
311
                *(int32_t *)vptr[5] = size;
312
        }
313
        break;
314
    case SOCKOP_shutdown:
315
        ret = get_errno(shutdown(vptr[0], vptr[1]));
316
        break;
317
    case SOCKOP_sendmsg:
318
    case SOCKOP_recvmsg:
319
    case SOCKOP_setsockopt:
320
    case SOCKOP_getsockopt:
321
    default:
322
        gemu_log("Unsupported socketcall: %d\n", num);
323
        ret = -ENOSYS;
324
        break;
325
    }
326
    return ret;
327
}
328

    
329
/* kernel structure types definitions */
330
#define IFNAMSIZ        16
331

    
332
#define STRUCT(name, list...) STRUCT_ ## name,
333
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
334
enum {
335
#include "syscall_types.h"
336
};
337
#undef STRUCT
338
#undef STRUCT_SPECIAL
339

    
340
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
341
#define STRUCT_SPECIAL(name)
342
#include "syscall_types.h"
343
#undef STRUCT
344
#undef STRUCT_SPECIAL
345

    
346
typedef struct IOCTLEntry {
347
    int target_cmd;
348
    int host_cmd;
349
    const char *name;
350
    int access;
351
    const argtype arg_type[3];
352
} IOCTLEntry;
353

    
354
#define IOC_R 0x0001
355
#define IOC_W 0x0002
356
#define IOC_RW (IOC_R | IOC_W)
357

    
358
#define MAX_STRUCT_SIZE 4096
359

    
360
const IOCTLEntry ioctl_entries[] = {
361
#define IOCTL(cmd, access, types...) \
362
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
363
#include "ioctls.h"
364
    { 0, 0, },
365
};
366

    
367
static long do_ioctl(long fd, long cmd, long arg)
368
{
369
    const IOCTLEntry *ie;
370
    const argtype *arg_type;
371
    long ret;
372
    uint8_t buf_temp[MAX_STRUCT_SIZE];
373

    
374
    ie = ioctl_entries;
375
    for(;;) {
376
        if (ie->target_cmd == 0) {
377
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
378
            return -ENOSYS;
379
        }
380
        if (ie->target_cmd == cmd)
381
            break;
382
        ie++;
383
    }
384
    arg_type = ie->arg_type;
385
    //    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
386
    switch(arg_type[0]) {
387
    case TYPE_NULL:
388
        /* no argument */
389
        ret = get_errno(ioctl(fd, ie->host_cmd));
390
        break;
391
    case TYPE_PTRVOID:
392
    case TYPE_INT:
393
        /* int argment */
394
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
395
        break;
396
    case TYPE_PTR:
397
        arg_type++;
398
        switch(ie->access) {
399
        case IOC_R:
400
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
401
            if (!is_error(ret)) {
402
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
403
            }
404
            break;
405
        case IOC_W:
406
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
407
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
408
            break;
409
        default:
410
        case IOC_RW:
411
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
412
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
413
            if (!is_error(ret)) {
414
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
415
            }
416
            break;
417
        }
418
        break;
419
    default:
420
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
421
        ret = -ENOSYS;
422
        break;
423
    }
424
    return ret;
425
}
426

    
427
bitmask_transtbl iflag_tbl[] = {
428
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
429
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
430
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
431
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
432
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
433
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
434
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
435
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
436
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
437
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
438
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
439
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
440
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
441
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
442
        { 0, 0, 0, 0 }
443
};
444

    
445
bitmask_transtbl oflag_tbl[] = {
446
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
447
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
448
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
449
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
450
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
451
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
452
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
453
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
454
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
455
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
456
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
457
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
458
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
459
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
460
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
461
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
462
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
463
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
464
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
465
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
466
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
467
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
468
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
469
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
470
        { 0, 0, 0, 0 }
471
};
472

    
473
bitmask_transtbl cflag_tbl[] = {
474
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
475
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
476
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
477
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
478
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
479
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
480
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
481
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
482
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
483
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
484
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
485
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
486
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
487
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
488
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
489
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
490
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
491
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
492
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
493
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
494
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
495
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
496
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
497
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
498
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
499
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
500
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
501
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
502
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
503
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
504
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
505
        { 0, 0, 0, 0 }
506
};
507

    
508
bitmask_transtbl lflag_tbl[] = {
509
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
510
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
511
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
512
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
513
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
514
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
515
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
516
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
517
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
518
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
519
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
520
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
521
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
522
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
523
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
524
        { 0, 0, 0, 0 }
525
};
526

    
527
static void target_to_host_termios (void *dst, const void *src)
528
{
529
    struct host_termios *host = dst;
530
    const struct target_termios *target = src;
531
    
532
    host->c_iflag = 
533
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
534
    host->c_oflag = 
535
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
536
    host->c_cflag = 
537
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
538
    host->c_lflag = 
539
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
540
    host->c_line = target->c_line;
541
    
542
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 
543
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 
544
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];       
545
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 
546
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];   
547
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 
548
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];   
549
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 
550
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];       
551
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 
552
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 
553
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];   
554
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];   
555
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];   
556
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];     
557
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];       
558
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 
559
}
560
  
561
static void host_to_target_termios (void *dst, const void *src)
562
{
563
    struct target_termios *target = dst;
564
    const struct host_termios *host = src;
565

    
566
    target->c_iflag = 
567
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
568
    target->c_oflag = 
569
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
570
    target->c_cflag = 
571
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
572
    target->c_lflag = 
573
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
574
    target->c_line = host->c_line;
575
  
576
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
577
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
578
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
579
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
580
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
581
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
582
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
583
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
584
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
585
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
586
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
587
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
588
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
589
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
590
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
591
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
592
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
593
}
594

    
595
StructEntry struct_termios_def = {
596
    .convert = { host_to_target_termios, target_to_host_termios },
597
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
598
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
599
};
600

    
601
void syscall_init(void)
602
{
603
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
604
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 
605
#include "syscall_types.h"
606
#undef STRUCT
607
#undef STRUCT_SPECIAL
608
}
609
                                 
610
long do_syscall(int num, long arg1, long arg2, long arg3, 
611
                long arg4, long arg5, long arg6)
612
{
613
    long ret;
614
    struct stat st;
615
    struct statfs *stfs;
616
    
617
    //    gemu_log("syscall %d\n", num);
618
    switch(num) {
619
    case TARGET_NR_exit:
620
        _exit(arg1);
621
        ret = 0; /* avoid warning */
622
        break;
623
    case TARGET_NR_read:
624
        ret = get_errno(read(arg1, (void *)arg2, arg3));
625
        break;
626
    case TARGET_NR_write:
627
        ret = get_errno(write(arg1, (void *)arg2, arg3));
628
        break;
629
    case TARGET_NR_open:
630
        ret = get_errno(open((const char *)arg1, arg2, arg3));
631
        break;
632
    case TARGET_NR_close:
633
        ret = get_errno(close(arg1));
634
        break;
635
    case TARGET_NR_brk:
636
        ret = do_brk((char *)arg1);
637
        break;
638
    case TARGET_NR_fork:
639
        ret = get_errno(fork());
640
        break;
641
    case TARGET_NR_waitpid:
642
        {
643
            int *status = (int *)arg2;
644
            ret = get_errno(waitpid(arg1, status, arg3));
645
            if (!is_error(ret) && status)
646
                tswapls((long *)&status);
647
        }
648
        break;
649
    case TARGET_NR_creat:
650
        ret = get_errno(creat((const char *)arg1, arg2));
651
        break;
652
    case TARGET_NR_link:
653
        ret = get_errno(link((const char *)arg1, (const char *)arg2));
654
        break;
655
    case TARGET_NR_unlink:
656
        ret = get_errno(unlink((const char *)arg1));
657
        break;
658
    case TARGET_NR_execve:
659
        ret = get_errno(execve((const char *)arg1, (void *)arg2, (void *)arg3));
660
        break;
661
    case TARGET_NR_chdir:
662
        ret = get_errno(chdir((const char *)arg1));
663
        break;
664
    case TARGET_NR_time:
665
        {
666
            int *time_ptr = (int *)arg1;
667
            ret = get_errno(time((time_t *)time_ptr));
668
            if (!is_error(ret) && time_ptr)
669
                tswap32s(time_ptr);
670
        }
671
        break;
672
    case TARGET_NR_mknod:
673
        ret = get_errno(mknod((const char *)arg1, arg2, arg3));
674
        break;
675
    case TARGET_NR_chmod:
676
        ret = get_errno(chmod((const char *)arg1, arg2));
677
        break;
678
    case TARGET_NR_lchown:
679
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
680
        break;
681
    case TARGET_NR_break:
682
        goto unimplemented;
683
    case TARGET_NR_oldstat:
684
        goto unimplemented;
685
    case TARGET_NR_lseek:
686
        ret = get_errno(lseek(arg1, arg2, arg3));
687
        break;
688
    case TARGET_NR_getpid:
689
        ret = get_errno(getpid());
690
        break;
691
    case TARGET_NR_mount:
692
        /* need to look at the data field */
693
        goto unimplemented;
694
    case TARGET_NR_umount:
695
        ret = get_errno(umount((const char *)arg1));
696
        break;
697
    case TARGET_NR_setuid:
698
        ret = get_errno(setuid(arg1));
699
        break;
700
    case TARGET_NR_getuid:
701
        ret = get_errno(getuid());
702
        break;
703
    case TARGET_NR_stime:
704
        {
705
            int *time_ptr = (int *)arg1;
706
            if (time_ptr)
707
                tswap32s(time_ptr);
708
            ret = get_errno(stime((time_t *)time_ptr));
709
        }
710
        break;
711
    case TARGET_NR_ptrace:
712
        goto unimplemented;
713
    case TARGET_NR_alarm:
714
        ret = alarm(arg1);
715
        break;
716
    case TARGET_NR_oldfstat:
717
        goto unimplemented;
718
    case TARGET_NR_pause:
719
        ret = get_errno(pause());
720
        break;
721
    case TARGET_NR_utime:
722
        goto unimplemented;
723
    case TARGET_NR_stty:
724
        goto unimplemented;
725
    case TARGET_NR_gtty:
726
        goto unimplemented;
727
    case TARGET_NR_access:
728
        ret = get_errno(access((const char *)arg1, arg2));
729
        break;
730
    case TARGET_NR_nice:
731
        ret = get_errno(nice(arg1));
732
        break;
733
    case TARGET_NR_ftime:
734
        goto unimplemented;
735
    case TARGET_NR_sync:
736
        ret = get_errno(sync());
737
        break;
738
    case TARGET_NR_kill:
739
        ret = get_errno(kill(arg1, arg2));
740
        break;
741
    case TARGET_NR_rename:
742
        ret = get_errno(rename((const char *)arg1, (const char *)arg2));
743
        break;
744
    case TARGET_NR_mkdir:
745
        ret = get_errno(mkdir((const char *)arg1, arg2));
746
        break;
747
    case TARGET_NR_rmdir:
748
        ret = get_errno(rmdir((const char *)arg1));
749
        break;
750
    case TARGET_NR_dup:
751
        ret = get_errno(dup(arg1));
752
        break;
753
    case TARGET_NR_pipe:
754
        {
755
            int *pipe_ptr = (int *)arg1;
756
            ret = get_errno(pipe(pipe_ptr));
757
            if (!is_error(ret)) {
758
                tswap32s(&pipe_ptr[0]);
759
                tswap32s(&pipe_ptr[1]);
760
            }
761
        }
762
        break;
763
    case TARGET_NR_times:
764
        goto unimplemented;
765
    case TARGET_NR_prof:
766
        goto unimplemented;
767
    case TARGET_NR_setgid:
768
        ret = get_errno(setgid(arg1));
769
        break;
770
    case TARGET_NR_getgid:
771
        ret = get_errno(getgid());
772
        break;
773
    case TARGET_NR_signal:
774
        goto unimplemented;
775
    case TARGET_NR_geteuid:
776
        ret = get_errno(geteuid());
777
        break;
778
    case TARGET_NR_getegid:
779
        ret = get_errno(getegid());
780
        break;
781
    case TARGET_NR_acct:
782
        goto unimplemented;
783
    case TARGET_NR_umount2:
784
        ret = get_errno(umount2((const char *)arg1, arg2));
785
        break;
786
    case TARGET_NR_lock:
787
        goto unimplemented;
788
    case TARGET_NR_ioctl:
789
        ret = do_ioctl(arg1, arg2, arg3);
790
        break;
791
    case TARGET_NR_fcntl:
792
        switch(arg2) {
793
        case F_GETLK:
794
        case F_SETLK:
795
        case F_SETLKW:
796
            goto unimplemented;
797
        default:
798
            ret = get_errno(fcntl(arg1, arg2, arg3));
799
            break;
800
        }
801
        break;
802
    case TARGET_NR_mpx:
803
        goto unimplemented;
804
    case TARGET_NR_setpgid:
805
        ret = get_errno(setpgid(arg1, arg2));
806
        break;
807
    case TARGET_NR_ulimit:
808
        goto unimplemented;
809
    case TARGET_NR_oldolduname:
810
        goto unimplemented;
811
    case TARGET_NR_umask:
812
        ret = get_errno(umask(arg1));
813
        break;
814
    case TARGET_NR_chroot:
815
        ret = get_errno(chroot((const char *)arg1));
816
        break;
817
    case TARGET_NR_ustat:
818
        goto unimplemented;
819
    case TARGET_NR_dup2:
820
        ret = get_errno(dup2(arg1, arg2));
821
        break;
822
    case TARGET_NR_getppid:
823
        ret = get_errno(getppid());
824
        break;
825
    case TARGET_NR_getpgrp:
826
        ret = get_errno(getpgrp());
827
        break;
828
    case TARGET_NR_setsid:
829
        ret = get_errno(setsid());
830
        break;
831
    case TARGET_NR_sigaction:
832
#if 0
833
        {
834
            int signum = arg1;
835
            struct target_old_sigaction *tact = arg2, *toldact = arg3;
836
            ret = get_errno(setsid());
837
            
838

839
        }
840
        break;
841
#else
842
        goto unimplemented;
843
#endif
844
    case TARGET_NR_sgetmask:
845
        goto unimplemented;
846
    case TARGET_NR_ssetmask:
847
        goto unimplemented;
848
    case TARGET_NR_setreuid:
849
        ret = get_errno(setreuid(arg1, arg2));
850
        break;
851
    case TARGET_NR_setregid:
852
        ret = get_errno(setregid(arg1, arg2));
853
        break;
854
    case TARGET_NR_sigsuspend:
855
        goto unimplemented;
856
    case TARGET_NR_sigpending:
857
        goto unimplemented;
858
    case TARGET_NR_sethostname:
859
        ret = get_errno(sethostname((const char *)arg1, arg2));
860
        break;
861
    case TARGET_NR_setrlimit:
862
        goto unimplemented;
863
    case TARGET_NR_getrlimit:
864
        goto unimplemented;
865
    case TARGET_NR_getrusage:
866
        goto unimplemented;
867
    case TARGET_NR_gettimeofday:
868
        {
869
            struct target_timeval *target_tv = (void *)arg1;
870
            struct timeval tv;
871
            ret = get_errno(gettimeofday(&tv, NULL));
872
            if (!is_error(ret)) {
873
                target_tv->tv_sec = tswapl(tv.tv_sec);
874
                target_tv->tv_usec = tswapl(tv.tv_usec);
875
            }
876
        }
877
        break;
878
    case TARGET_NR_settimeofday:
879
        {
880
            struct target_timeval *target_tv = (void *)arg1;
881
            struct timeval tv;
882
            tv.tv_sec = tswapl(target_tv->tv_sec);
883
            tv.tv_usec = tswapl(target_tv->tv_usec);
884
            ret = get_errno(settimeofday(&tv, NULL));
885
        }
886
        break;
887
    case TARGET_NR_getgroups:
888
        goto unimplemented;
889
    case TARGET_NR_setgroups:
890
        goto unimplemented;
891
    case TARGET_NR_select:
892
        goto unimplemented;
893
    case TARGET_NR_symlink:
894
        ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
895
        break;
896
    case TARGET_NR_oldlstat:
897
        goto unimplemented;
898
    case TARGET_NR_readlink:
899
        ret = get_errno(readlink((const char *)arg1, (char *)arg2, arg3));
900
        break;
901
    case TARGET_NR_uselib:
902
        goto unimplemented;
903
    case TARGET_NR_swapon:
904
        ret = get_errno(swapon((const char *)arg1, arg2));
905
        break;
906
    case TARGET_NR_reboot:
907
        goto unimplemented;
908
    case TARGET_NR_readdir:
909
        goto unimplemented;
910
#ifdef TARGET_I386
911
    case TARGET_NR_mmap:
912
        {
913
            uint32_t v1, v2, v3, v4, v5, v6, *vptr;
914
            vptr = (uint32_t *)arg1;
915
            v1 = tswap32(vptr[0]);
916
            v2 = tswap32(vptr[1]);
917
            v3 = tswap32(vptr[2]);
918
            v4 = tswap32(vptr[3]);
919
            v5 = tswap32(vptr[4]);
920
            v6 = tswap32(vptr[5]);
921
            ret = get_errno((long)mmap((void *)v1, v2, v3, v4, v5, v6));
922
        }
923
        break;
924
#endif
925
#ifdef TARGET_I386
926
    case TARGET_NR_mmap2:
927
#else
928
    case TARGET_NR_mmap:
929
#endif
930
        ret = get_errno((long)mmap((void *)arg1, arg2, arg3, arg4, arg5, arg6));
931
        break;
932
    case TARGET_NR_munmap:
933
        ret = get_errno(munmap((void *)arg1, arg2));
934
        break;
935
    case TARGET_NR_truncate:
936
        ret = get_errno(truncate((const char *)arg1, arg2));
937
        break;
938
    case TARGET_NR_ftruncate:
939
        ret = get_errno(ftruncate(arg1, arg2));
940
        break;
941
    case TARGET_NR_fchmod:
942
        ret = get_errno(fchmod(arg1, arg2));
943
        break;
944
    case TARGET_NR_fchown:
945
        ret = get_errno(fchown(arg1, arg2, arg3));
946
        break;
947
    case TARGET_NR_getpriority:
948
        ret = get_errno(getpriority(arg1, arg2));
949
        break;
950
    case TARGET_NR_setpriority:
951
        ret = get_errno(setpriority(arg1, arg2, arg3));
952
        break;
953
    case TARGET_NR_profil:
954
        goto unimplemented;
955
    case TARGET_NR_statfs:
956
        stfs = (void *)arg2;
957
        ret = get_errno(sys_statfs((const char *)arg1, stfs));
958
    convert_statfs:
959
        if (!is_error(ret)) {
960
            tswap32s(&stfs->f_type);
961
            tswap32s(&stfs->f_bsize);
962
            tswap32s(&stfs->f_blocks);
963
            tswap32s(&stfs->f_bfree);
964
            tswap32s(&stfs->f_bavail);
965
            tswap32s(&stfs->f_files);
966
            tswap32s(&stfs->f_ffree);
967
            tswap32s(&stfs->f_fsid.val[0]);
968
            tswap32s(&stfs->f_fsid.val[1]);
969
            tswap32s(&stfs->f_namelen);
970
        }
971
        break;
972
    case TARGET_NR_fstatfs:
973
        stfs = (void *)arg2;
974
        ret = get_errno(sys_fstatfs(arg1, stfs));
975
        goto convert_statfs;
976
    case TARGET_NR_ioperm:
977
        goto unimplemented;
978
    case TARGET_NR_socketcall:
979
        ret = do_socketcall(arg1, (long *)arg2);
980
        break;
981
    case TARGET_NR_syslog:
982
        goto unimplemented;
983
    case TARGET_NR_setitimer:
984
        goto unimplemented;
985
    case TARGET_NR_getitimer:
986
        goto unimplemented;
987
    case TARGET_NR_stat:
988
        ret = get_errno(stat((const char *)arg1, &st));
989
        goto do_stat;
990
    case TARGET_NR_lstat:
991
        ret = get_errno(lstat((const char *)arg1, &st));
992
        goto do_stat;
993
    case TARGET_NR_fstat:
994
        {
995
            ret = get_errno(fstat(arg1, &st));
996
        do_stat:
997
            if (!is_error(ret)) {
998
                struct target_stat *target_st = (void *)arg2;
999
                target_st->st_dev = tswap16(st.st_dev);
1000
                target_st->st_ino = tswapl(st.st_ino);
1001
                target_st->st_mode = tswap16(st.st_mode);
1002
                target_st->st_nlink = tswap16(st.st_nlink);
1003
                target_st->st_uid = tswap16(st.st_uid);
1004
                target_st->st_gid = tswap16(st.st_gid);
1005
                target_st->st_rdev = tswap16(st.st_rdev);
1006
                target_st->st_size = tswapl(st.st_size);
1007
                target_st->st_blksize = tswapl(st.st_blksize);
1008
                target_st->st_blocks = tswapl(st.st_blocks);
1009
                target_st->st_atime = tswapl(st.st_atime);
1010
                target_st->st_mtime = tswapl(st.st_mtime);
1011
                target_st->st_ctime = tswapl(st.st_ctime);
1012
            }
1013
        }
1014
        break;
1015
    case TARGET_NR_olduname:
1016
        goto unimplemented;
1017
    case TARGET_NR_iopl:
1018
        goto unimplemented;
1019
    case TARGET_NR_vhangup:
1020
        ret = get_errno(vhangup());
1021
        break;
1022
    case TARGET_NR_idle:
1023
        goto unimplemented;
1024
    case TARGET_NR_vm86old:
1025
        goto unimplemented;
1026
    case TARGET_NR_wait4:
1027
        {
1028
            int status;
1029
            target_long *status_ptr = (void *)arg2;
1030
            struct rusage rusage, *rusage_ptr;
1031
            struct target_rusage *target_rusage = (void *)arg4;
1032
            if (target_rusage)
1033
                rusage_ptr = &rusage;
1034
            else
1035
                rusage_ptr = NULL;
1036
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
1037
            if (!is_error(ret)) {
1038
                if (status_ptr)
1039
                    *status_ptr = tswap32(status);
1040
                if (target_rusage) {
1041
                    target_rusage->ru_utime.tv_sec = tswapl(rusage.ru_utime.tv_sec);
1042
                    target_rusage->ru_utime.tv_usec = tswapl(rusage.ru_utime.tv_usec);
1043
                    target_rusage->ru_stime.tv_sec = tswapl(rusage.ru_stime.tv_sec);
1044
                    target_rusage->ru_stime.tv_usec = tswapl(rusage.ru_stime.tv_usec);
1045
                    target_rusage->ru_maxrss = tswapl(rusage.ru_maxrss);
1046
                    target_rusage->ru_ixrss = tswapl(rusage.ru_ixrss);
1047
                    target_rusage->ru_idrss = tswapl(rusage.ru_idrss);
1048
                    target_rusage->ru_isrss = tswapl(rusage.ru_isrss);
1049
                    target_rusage->ru_minflt = tswapl(rusage.ru_minflt);
1050
                    target_rusage->ru_majflt = tswapl(rusage.ru_majflt);
1051
                    target_rusage->ru_nswap = tswapl(rusage.ru_nswap);
1052
                    target_rusage->ru_inblock = tswapl(rusage.ru_inblock);
1053
                    target_rusage->ru_oublock = tswapl(rusage.ru_oublock);
1054
                    target_rusage->ru_msgsnd = tswapl(rusage.ru_msgsnd);
1055
                    target_rusage->ru_msgrcv = tswapl(rusage.ru_msgrcv);
1056
                    target_rusage->ru_nsignals = tswapl(rusage.ru_nsignals);
1057
                    target_rusage->ru_nvcsw = tswapl(rusage.ru_nvcsw);
1058
                    target_rusage->ru_nivcsw = tswapl(rusage.ru_nivcsw);
1059
                }
1060
            }
1061
        }
1062
        break;
1063
    case TARGET_NR_swapoff:
1064
        ret = get_errno(swapoff((const char *)arg1));
1065
        break;
1066
    case TARGET_NR_sysinfo:
1067
        goto unimplemented;
1068
    case TARGET_NR_ipc:
1069
        goto unimplemented;
1070
    case TARGET_NR_fsync:
1071
        ret = get_errno(fsync(arg1));
1072
        break;
1073
    case TARGET_NR_sigreturn:
1074
        goto unimplemented;
1075
    case TARGET_NR_clone:
1076
        goto unimplemented;
1077
    case TARGET_NR_setdomainname:
1078
        ret = get_errno(setdomainname((const char *)arg1, arg2));
1079
        break;
1080
    case TARGET_NR_uname:
1081
        /* no need to transcode because we use the linux syscall */
1082
        ret = get_errno(sys_uname((struct new_utsname *)arg1));
1083
        break;
1084
    case TARGET_NR_modify_ldt:
1085
        goto unimplemented;
1086
    case TARGET_NR_adjtimex:
1087
        goto unimplemented;
1088
    case TARGET_NR_mprotect:
1089
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1090
        break;
1091
    case TARGET_NR_sigprocmask:
1092
        {
1093
            int how = arg1;
1094
            sigset_t set, oldset, *set_ptr;
1095
            target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
1096
            
1097
            switch(how) {
1098
            case TARGET_SIG_BLOCK:
1099
                how = SIG_BLOCK;
1100
                break;
1101
            case TARGET_SIG_UNBLOCK:
1102
                how = SIG_UNBLOCK;
1103
                break;
1104
            case TARGET_SIG_SETMASK:
1105
                how = SIG_SETMASK;
1106
                break;
1107
            default:
1108
                ret = -EINVAL;
1109
                goto fail;
1110
            }
1111
            
1112
            if (pset) {
1113
                target_to_host_old_sigset(&set, pset);
1114
                set_ptr = &set;
1115
            } else {
1116
                set_ptr = NULL;
1117
            }
1118
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1119
            if (!is_error(ret) && poldset) {
1120
                host_to_target_old_sigset(poldset, &oldset);
1121
            }
1122
        }
1123
        break;
1124
    case TARGET_NR_create_module:
1125
    case TARGET_NR_init_module:
1126
    case TARGET_NR_delete_module:
1127
    case TARGET_NR_get_kernel_syms:
1128
        goto unimplemented;
1129
    case TARGET_NR_quotactl:
1130
        goto unimplemented;
1131
    case TARGET_NR_getpgid:
1132
        ret = get_errno(getpgid(arg1));
1133
        break;
1134
    case TARGET_NR_fchdir:
1135
        ret = get_errno(fchdir(arg1));
1136
        break;
1137
    case TARGET_NR_bdflush:
1138
        goto unimplemented;
1139
    case TARGET_NR_sysfs:
1140
        goto unimplemented;
1141
    case TARGET_NR_personality:
1142
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1143
        break;
1144
    case TARGET_NR_afs_syscall:
1145
        goto unimplemented;
1146
    case TARGET_NR_setfsuid:
1147
        goto unimplemented;
1148
    case TARGET_NR_setfsgid:
1149
        goto unimplemented;
1150
    case TARGET_NR__llseek:
1151
        {
1152
            int64_t res;
1153
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
1154
            *(int64_t *)arg4 = tswap64(res);
1155
        }
1156
        break;
1157
    case TARGET_NR_getdents:
1158
#if TARGET_LONG_SIZE != 4
1159
#error not supported
1160
#endif
1161
        {
1162
            struct dirent *dirp = (void *)arg2;
1163
            long count = arg3;
1164
            ret = get_errno(getdents(arg1, dirp, count));
1165
            if (!is_error(ret)) {
1166
                struct dirent *de;
1167
                int len = ret;
1168
                int reclen;
1169
                de = dirp;
1170
                while (len > 0) {
1171
                    reclen = tswap16(de->d_reclen);
1172
                    if (reclen > len)
1173
                        break;
1174
                    de->d_reclen = reclen;
1175
                    tswapls(&de->d_ino);
1176
                    tswapls(&de->d_off);
1177
                    de = (struct dirent *)((char *)de + reclen);
1178
                    len -= reclen;
1179
                }
1180
            }
1181
        }
1182
        break;
1183
    case TARGET_NR__newselect:
1184
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
1185
                        (void *)arg5);
1186
        break;
1187
    case TARGET_NR_flock:
1188
        goto unimplemented;
1189
    case TARGET_NR_msync:
1190
        ret = get_errno(msync((void *)arg1, arg2, arg3));
1191
        break;
1192
    case TARGET_NR_readv:
1193
        {
1194
            int count = arg3;
1195
            int i;
1196
            struct iovec *vec;
1197
            struct target_iovec *target_vec = (void *)arg2;
1198

    
1199
            vec = alloca(count * sizeof(struct iovec));
1200
            for(i = 0;i < count; i++) {
1201
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1202
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
1203
            }
1204
            ret = get_errno(readv(arg1, vec, count));
1205
        }
1206
        break;
1207
    case TARGET_NR_writev:
1208
        {
1209
            int count = arg3;
1210
            int i;
1211
            struct iovec *vec;
1212
            struct target_iovec *target_vec = (void *)arg2;
1213

    
1214
            vec = alloca(count * sizeof(struct iovec));
1215
            for(i = 0;i < count; i++) {
1216
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1217
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
1218
            }
1219
            ret = get_errno(writev(arg1, vec, count));
1220
        }
1221
        break;
1222
    case TARGET_NR_getsid:
1223
        ret = get_errno(getsid(arg1));
1224
        break;
1225
    case TARGET_NR_fdatasync:
1226
        goto unimplemented;
1227
    case TARGET_NR__sysctl:
1228
        goto unimplemented;
1229
    case TARGET_NR_mlock:
1230
        ret = get_errno(mlock((void *)arg1, arg2));
1231
        break;
1232
    case TARGET_NR_munlock:
1233
        ret = get_errno(munlock((void *)arg1, arg2));
1234
        break;
1235
    case TARGET_NR_mlockall:
1236
        ret = get_errno(mlockall(arg1));
1237
        break;
1238
    case TARGET_NR_munlockall:
1239
        ret = get_errno(munlockall());
1240
        break;
1241
    case TARGET_NR_sched_setparam:
1242
        goto unimplemented;
1243
    case TARGET_NR_sched_getparam:
1244
        goto unimplemented;
1245
    case TARGET_NR_sched_setscheduler:
1246
        goto unimplemented;
1247
    case TARGET_NR_sched_getscheduler:
1248
        goto unimplemented;
1249
    case TARGET_NR_sched_yield:
1250
        ret = get_errno(sched_yield());
1251
        break;
1252
    case TARGET_NR_sched_get_priority_max:
1253
    case TARGET_NR_sched_get_priority_min:
1254
    case TARGET_NR_sched_rr_get_interval:
1255
    case TARGET_NR_nanosleep:
1256
    case TARGET_NR_mremap:
1257
    case TARGET_NR_setresuid:
1258
    case TARGET_NR_getresuid:
1259
    case TARGET_NR_vm86:
1260
    case TARGET_NR_query_module:
1261
    case TARGET_NR_poll:
1262
    case TARGET_NR_nfsservctl:
1263
    case TARGET_NR_setresgid:
1264
    case TARGET_NR_getresgid:
1265
    case TARGET_NR_prctl:
1266
    case TARGET_NR_rt_sigreturn:
1267
    case TARGET_NR_rt_sigaction:
1268
    case TARGET_NR_rt_sigprocmask:
1269
    case TARGET_NR_rt_sigpending:
1270
    case TARGET_NR_rt_sigtimedwait:
1271
    case TARGET_NR_rt_sigqueueinfo:
1272
    case TARGET_NR_rt_sigsuspend:
1273
    case TARGET_NR_pread:
1274
    case TARGET_NR_pwrite:
1275
        goto unimplemented;
1276
    case TARGET_NR_chown:
1277
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
1278
        break;
1279
    case TARGET_NR_getcwd:
1280
        ret = get_errno(sys_getcwd((char *)arg1, arg2));
1281
        break;
1282
    case TARGET_NR_capget:
1283
    case TARGET_NR_capset:
1284
    case TARGET_NR_sigaltstack:
1285
    case TARGET_NR_sendfile:
1286
    case TARGET_NR_getpmsg:
1287
    case TARGET_NR_putpmsg:
1288
    case TARGET_NR_vfork:
1289
        ret = get_errno(vfork());
1290
        break;
1291
    case TARGET_NR_ugetrlimit:
1292
    case TARGET_NR_truncate64:
1293
    case TARGET_NR_ftruncate64:
1294
    case TARGET_NR_stat64:
1295
    case TARGET_NR_lstat64:
1296
    case TARGET_NR_fstat64:
1297
    case TARGET_NR_lchown32:
1298
    case TARGET_NR_getuid32:
1299
    case TARGET_NR_getgid32:
1300
    case TARGET_NR_geteuid32:
1301
    case TARGET_NR_getegid32:
1302
    case TARGET_NR_setreuid32:
1303
    case TARGET_NR_setregid32:
1304
    case TARGET_NR_getgroups32:
1305
    case TARGET_NR_setgroups32:
1306
    case TARGET_NR_fchown32:
1307
    case TARGET_NR_setresuid32:
1308
    case TARGET_NR_getresuid32:
1309
    case TARGET_NR_setresgid32:
1310
    case TARGET_NR_getresgid32:
1311
    case TARGET_NR_chown32:
1312
    case TARGET_NR_setuid32:
1313
    case TARGET_NR_setgid32:
1314
    case TARGET_NR_setfsuid32:
1315
    case TARGET_NR_setfsgid32:
1316
    case TARGET_NR_pivot_root:
1317
    case TARGET_NR_mincore:
1318
    case TARGET_NR_madvise:
1319
    case TARGET_NR_getdents64:
1320
    case TARGET_NR_fcntl64:
1321
    case TARGET_NR_security:
1322
        goto unimplemented;
1323
    case TARGET_NR_gettid:
1324
        ret = get_errno(gettid());
1325
        break;
1326
    case TARGET_NR_readahead:
1327
    case TARGET_NR_setxattr:
1328
    case TARGET_NR_lsetxattr:
1329
    case TARGET_NR_fsetxattr:
1330
    case TARGET_NR_getxattr:
1331
    case TARGET_NR_lgetxattr:
1332
    case TARGET_NR_fgetxattr:
1333
    case TARGET_NR_listxattr:
1334
    case TARGET_NR_llistxattr:
1335
    case TARGET_NR_flistxattr:
1336
    case TARGET_NR_removexattr:
1337
    case TARGET_NR_lremovexattr:
1338
    case TARGET_NR_fremovexattr:
1339
        goto unimplemented;
1340
    default:
1341
    unimplemented:
1342
        gemu_log("Unsupported syscall: %d\n", num);
1343
        ret = -ENOSYS;
1344
        break;
1345
    }
1346
 fail:
1347
    return ret;
1348
}
1349