Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 04369ff2

History | View | Annotate | Download (48.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 <sys/types.h>
30
#include <sys/wait.h>
31
#include <sys/time.h>
32
#include <sys/stat.h>
33
#include <sys/mount.h>
34
#include <sys/resource.h>
35
#include <sys/mman.h>
36
#include <sys/swap.h>
37
#include <signal.h>
38
#include <sched.h>
39
#include <sys/socket.h>
40
#include <sys/uio.h>
41
//#include <sys/user.h>
42

    
43
#define termios host_termios
44
#define winsize host_winsize
45
#define termio host_termio
46
#define sgttyb host_sgttyb /* same as target */
47
#define tchars host_tchars /* same as target */
48
#define ltchars host_ltchars /* same as target */
49

    
50
#include <linux/termios.h>
51
#include <linux/unistd.h>
52
#include <linux/utsname.h>
53
#include <linux/cdrom.h>
54
#include <linux/hdreg.h>
55
#include <linux/soundcard.h>
56

    
57
#include "gemu.h"
58

    
59
//#define DEBUG
60

    
61
#ifndef PAGE_SIZE
62
#define PAGE_SIZE 4096
63
#define PAGE_MASK ~(PAGE_SIZE - 1)
64
#endif
65

    
66
struct dirent {
67
        long            d_ino;
68
        long            d_off;
69
        unsigned short  d_reclen;
70
        char            d_name[256]; /* We must not include limits.h! */
71
};
72

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

    
77
#include "syscall_defs.h"
78

    
79
#ifdef TARGET_I386
80
#include "cpu-i386.h"
81
#include "syscall-i386.h"
82
#endif
83

    
84
#define __NR_sys_uname __NR_uname
85
#define __NR_sys_getcwd1 __NR_getcwd
86
#define __NR_sys_statfs __NR_statfs
87
#define __NR_sys_fstatfs __NR_fstatfs
88
#define __NR_sys_getdents __NR_getdents
89

    
90
#ifdef __NR_gettid
91
_syscall0(int, gettid)
92
#else
93
static int gettid(void) {
94
    return -ENOSYS;
95
}
96
#endif
97
_syscall1(int,sys_uname,struct new_utsname *,buf)
98
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
99
_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
100
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
101
          loff_t *, res, uint, wh);
102
_syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
103
_syscall2(int,sys_fstatfs,int,fd,struct kernel_statfs *,buf)
104

    
105
static inline long get_errno(long ret)
106
{
107
    if (ret == -1)
108
        return -errno;
109
    else
110
        return ret;
111
}
112

    
113
static inline int is_error(long ret)
114
{
115
    return (unsigned long)ret >= (unsigned long)(-4096);
116
}
117

    
118
static char *target_brk;
119
static char *target_original_brk;
120

    
121
void target_set_brk(char *new_brk)
122
{
123
    target_brk = new_brk;
124
    target_original_brk = new_brk;
125
}
126

    
127
static long do_brk(char *new_brk)
128
{
129
    char *brk_page;
130
    long mapped_addr;
131
    int        new_alloc_size;
132

    
133
    if (!new_brk)
134
        return (long)target_brk;
135
    if (new_brk < target_original_brk)
136
        return -ENOMEM;
137
    
138
    brk_page = (char *)(((unsigned long)target_brk + PAGE_SIZE - 1) & PAGE_MASK);
139

    
140
    /* If the new brk is less than this, set it and we're done... */
141
    if (new_brk < brk_page) {
142
        target_brk = new_brk;
143
            return (long)target_brk;
144
    }
145

    
146
    /* We need to allocate more memory after the brk... */
147
    new_alloc_size = ((new_brk - brk_page + 1)+(PAGE_SIZE-1)) & PAGE_MASK;
148
    mapped_addr = get_errno((long)mmap((caddr_t)brk_page, new_alloc_size, 
149
                                       PROT_READ|PROT_WRITE,
150
                                       MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
151
    
152
    if (is_error(mapped_addr)) {
153
        return mapped_addr;
154
    } else {
155
        target_brk = new_brk;
156
            return (long)target_brk;
157
    }
158
}
159

    
160
static inline fd_set *target_to_host_fds(fd_set *fds, 
161
                                         target_long *target_fds, int n)
162
{
163
#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
164
    return (fd_set *)target_fds;
165
#else
166
    int i, b;
167
    if (target_fds) {
168
        FD_ZERO(fds);
169
        for(i = 0;i < n; i++) {
170
            b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
171
                 (i & (TARGET_LONG_BITS - 1))) & 1;
172
            if (b)
173
                FD_SET(i, fds);
174
        }
175
        return fds;
176
    } else {
177
        return NULL;
178
    }
179
#endif
180
}
181

    
182
static inline void host_to_target_fds(target_long *target_fds, 
183
                                      fd_set *fds, int n)
184
{
185
#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
186
    /* nothing to do */
187
#else
188
    int i, nw, j, k;
189
    target_long v;
190

    
191
    if (target_fds) {
192
        nw = n / TARGET_LONG_BITS;
193
        k = 0;
194
        for(i = 0;i < nw; i++) {
195
            v = 0;
196
            for(j = 0; j < TARGET_LONG_BITS; j++) {
197
                v |= ((FD_ISSET(k, fds) != 0) << j);
198
                k++;
199
            }
200
            target_fds[i] = tswapl(v);
201
        }
202
    }
203
#endif
204
}
205

    
206
/* XXX: incorrect for some archs */
207
static void host_to_target_old_sigset(target_ulong *old_sigset, 
208
                                      const sigset_t *sigset)
209
{
210
    *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
211
}
212

    
213
static void target_to_host_old_sigset(sigset_t *sigset, 
214
                                      const target_ulong *old_sigset)
215
{
216
    sigemptyset(sigset);
217
    *(unsigned long *)sigset = tswapl(*old_sigset);
218
}
219

    
220

    
221
static long do_select(long n, 
222
                      target_long *target_rfds, target_long *target_wfds, 
223
                      target_long *target_efds, struct target_timeval *target_tv)
224
{
225
    fd_set rfds, wfds, efds;
226
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
227
    struct timeval tv, *tv_ptr;
228
    long ret;
229

    
230
    rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
231
    wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
232
    efds_ptr = target_to_host_fds(&efds, target_efds, n);
233
            
234
    if (target_tv) {
235
        tv.tv_sec = tswapl(target_tv->tv_sec);
236
        tv.tv_usec = tswapl(target_tv->tv_usec);
237
        tv_ptr = &tv;
238
    } else {
239
        tv_ptr = NULL;
240
    }
241
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
242
    if (!is_error(ret)) {
243
        host_to_target_fds(target_rfds, rfds_ptr, n);
244
        host_to_target_fds(target_wfds, wfds_ptr, n);
245
        host_to_target_fds(target_efds, efds_ptr, n);
246

    
247
        if (target_tv) {
248
            target_tv->tv_sec = tswapl(tv.tv_sec);
249
            target_tv->tv_usec = tswapl(tv.tv_usec);
250
        }
251
    }
252
    return ret;
253
}
254

    
255
static long do_socketcall(int num, long *vptr)
256
{
257
    long ret;
258

    
259
    switch(num) {
260
    case SOCKOP_socket:
261
        ret = get_errno(socket(vptr[0], vptr[1], vptr[2]));
262
        break;
263
    case SOCKOP_bind:
264
        ret = get_errno(bind(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
265
        break;
266
    case SOCKOP_connect:
267
        ret = get_errno(connect(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
268
        break;
269
    case SOCKOP_listen:
270
        ret = get_errno(listen(vptr[0], vptr[1]));
271
        break;
272
    case SOCKOP_accept:
273
        {
274
            socklen_t size;
275
            size = tswap32(*(int32_t *)vptr[2]);
276
            ret = get_errno(accept(vptr[0], (struct sockaddr *)vptr[1], &size));
277
            if (!is_error(ret)) 
278
                *(int32_t *)vptr[2] = size;
279
        }
280
        break;
281
    case SOCKOP_getsockname:
282
        {
283
            socklen_t size;
284
            size = tswap32(*(int32_t *)vptr[2]);
285
            ret = get_errno(getsockname(vptr[0], (struct sockaddr *)vptr[1], &size));
286
            if (!is_error(ret)) 
287
                *(int32_t *)vptr[2] = size;
288
        }
289
        break;
290
    case SOCKOP_getpeername:
291
        {
292
            socklen_t size;
293
            size = tswap32(*(int32_t *)vptr[2]);
294
            ret = get_errno(getpeername(vptr[0], (struct sockaddr *)vptr[1], &size));
295
            if (!is_error(ret)) 
296
                *(int32_t *)vptr[2] = size;
297
        }
298
        break;
299
    case SOCKOP_socketpair:
300
        {
301
            int tab[2];
302
            int32_t *target_tab = (int32_t *)vptr[3];
303
            ret = get_errno(socketpair(vptr[0], vptr[1], vptr[2], tab));
304
            if (!is_error(ret)) {
305
                target_tab[0] = tswap32(tab[0]);
306
                target_tab[1] = tswap32(tab[1]);
307
            }
308
        }
309
        break;
310
    case SOCKOP_send:
311
        ret = get_errno(send(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
312
        break;
313
    case SOCKOP_recv:
314
        ret = get_errno(recv(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
315
        break;
316
    case SOCKOP_sendto:
317
        ret = get_errno(sendto(vptr[0], (void *)vptr[1], vptr[2], vptr[3], 
318
                               (struct sockaddr *)vptr[4], vptr[5]));
319
        break;
320
    case SOCKOP_recvfrom:
321
        {
322
            socklen_t size;
323
            size = tswap32(*(int32_t *)vptr[5]);
324
            ret = get_errno(recvfrom(vptr[0], (void *)vptr[1], vptr[2], 
325
                                     vptr[3], (struct sockaddr *)vptr[4], &size));
326
            if (!is_error(ret)) 
327
                *(int32_t *)vptr[5] = size;
328
        }
329
        break;
330
    case SOCKOP_shutdown:
331
        ret = get_errno(shutdown(vptr[0], vptr[1]));
332
        break;
333
    case SOCKOP_sendmsg:
334
    case SOCKOP_recvmsg:
335
        {
336
            int fd;
337
            struct target_msghdr *msgp;
338
            struct msghdr msg;
339
            int flags, count, i;
340
            struct iovec *vec;
341
            struct target_iovec *target_vec;
342

    
343
            msgp = (void *)vptr[1];
344
            msg.msg_name = (void *)tswapl(msgp->msg_name);
345
            msg.msg_namelen = tswapl(msgp->msg_namelen);
346
            msg.msg_control = (void *)tswapl(msgp->msg_control);
347
            msg.msg_controllen = tswapl(msgp->msg_controllen);
348
            msg.msg_flags = tswap32(msgp->msg_flags);
349

    
350
            count = tswapl(msgp->msg_iovlen);
351
            vec = alloca(count * sizeof(struct iovec));
352
            target_vec = (void *)tswapl(msgp->msg_iov);
353
            for(i = 0;i < count; i++) {
354
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
355
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
356
            }
357
            msg.msg_iovlen = count;
358
            msg.msg_iov = vec;
359

    
360
            fd = vptr[0];
361
            flags = vptr[2];
362
            if (num == SOCKOP_sendmsg)
363
                ret = sendmsg(fd, &msg, flags);
364
            else
365
                ret = recvmsg(fd, &msg, flags);
366
            ret = get_errno(ret);
367
        }
368
        break;
369
    case SOCKOP_setsockopt:
370
    case SOCKOP_getsockopt:
371
    default:
372
        gemu_log("Unsupported socketcall: %d\n", num);
373
        ret = -ENOSYS;
374
        break;
375
    }
376
    return ret;
377
}
378

    
379
/* kernel structure types definitions */
380
#define IFNAMSIZ        16
381

    
382
#define STRUCT(name, list...) STRUCT_ ## name,
383
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
384
enum {
385
#include "syscall_types.h"
386
};
387
#undef STRUCT
388
#undef STRUCT_SPECIAL
389

    
390
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
391
#define STRUCT_SPECIAL(name)
392
#include "syscall_types.h"
393
#undef STRUCT
394
#undef STRUCT_SPECIAL
395

    
396
typedef struct IOCTLEntry {
397
    int target_cmd;
398
    int host_cmd;
399
    const char *name;
400
    int access;
401
    const argtype arg_type[5];
402
} IOCTLEntry;
403

    
404
#define IOC_R 0x0001
405
#define IOC_W 0x0002
406
#define IOC_RW (IOC_R | IOC_W)
407

    
408
#define MAX_STRUCT_SIZE 4096
409

    
410
const IOCTLEntry ioctl_entries[] = {
411
#define IOCTL(cmd, access, types...) \
412
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
413
#include "ioctls.h"
414
    { 0, 0, },
415
};
416

    
417
static long do_ioctl(long fd, long cmd, long arg)
418
{
419
    const IOCTLEntry *ie;
420
    const argtype *arg_type;
421
    long ret;
422
    uint8_t buf_temp[MAX_STRUCT_SIZE];
423

    
424
    ie = ioctl_entries;
425
    for(;;) {
426
        if (ie->target_cmd == 0) {
427
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
428
            return -ENOSYS;
429
        }
430
        if (ie->target_cmd == cmd)
431
            break;
432
        ie++;
433
    }
434
    arg_type = ie->arg_type;
435
#ifdef DEBUG
436
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
437
#endif
438
    switch(arg_type[0]) {
439
    case TYPE_NULL:
440
        /* no argument */
441
        ret = get_errno(ioctl(fd, ie->host_cmd));
442
        break;
443
    case TYPE_PTRVOID:
444
    case TYPE_INT:
445
        /* int argment */
446
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
447
        break;
448
    case TYPE_PTR:
449
        arg_type++;
450
        switch(ie->access) {
451
        case IOC_R:
452
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
453
            if (!is_error(ret)) {
454
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
455
            }
456
            break;
457
        case IOC_W:
458
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
459
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
460
            break;
461
        default:
462
        case IOC_RW:
463
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
464
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
465
            if (!is_error(ret)) {
466
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
467
            }
468
            break;
469
        }
470
        break;
471
    default:
472
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
473
        ret = -ENOSYS;
474
        break;
475
    }
476
    return ret;
477
}
478

    
479
bitmask_transtbl iflag_tbl[] = {
480
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
481
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
482
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
483
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
484
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
485
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
486
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
487
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
488
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
489
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
490
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
491
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
492
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
493
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
494
        { 0, 0, 0, 0 }
495
};
496

    
497
bitmask_transtbl oflag_tbl[] = {
498
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
499
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
500
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
501
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
502
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
503
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
504
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
505
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
506
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
507
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
508
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
509
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
510
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
511
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
512
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
513
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
514
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
515
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
516
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
517
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
518
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
519
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
520
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
521
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
522
        { 0, 0, 0, 0 }
523
};
524

    
525
bitmask_transtbl cflag_tbl[] = {
526
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
527
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
528
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
529
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
530
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
531
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
532
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
533
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
534
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
535
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
536
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
537
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
538
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
539
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
540
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
541
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
542
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
543
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
544
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
545
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
546
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
547
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
548
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
549
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
550
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
551
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
552
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
553
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
554
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
555
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
556
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
557
        { 0, 0, 0, 0 }
558
};
559

    
560
bitmask_transtbl lflag_tbl[] = {
561
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
562
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
563
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
564
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
565
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
566
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
567
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
568
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
569
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
570
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
571
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
572
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
573
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
574
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
575
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
576
        { 0, 0, 0, 0 }
577
};
578

    
579
static void target_to_host_termios (void *dst, const void *src)
580
{
581
    struct host_termios *host = dst;
582
    const struct target_termios *target = src;
583
    
584
    host->c_iflag = 
585
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
586
    host->c_oflag = 
587
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
588
    host->c_cflag = 
589
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
590
    host->c_lflag = 
591
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
592
    host->c_line = target->c_line;
593
    
594
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 
595
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 
596
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];       
597
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 
598
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];   
599
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 
600
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];   
601
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 
602
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];       
603
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 
604
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 
605
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];   
606
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];   
607
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];   
608
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];     
609
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];       
610
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 
611
}
612
  
613
static void host_to_target_termios (void *dst, const void *src)
614
{
615
    struct target_termios *target = dst;
616
    const struct host_termios *host = src;
617

    
618
    target->c_iflag = 
619
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
620
    target->c_oflag = 
621
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
622
    target->c_cflag = 
623
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
624
    target->c_lflag = 
625
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
626
    target->c_line = host->c_line;
627
  
628
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
629
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
630
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
631
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
632
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
633
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
634
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
635
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
636
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
637
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
638
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
639
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
640
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
641
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
642
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
643
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
644
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
645
}
646

    
647
StructEntry struct_termios_def = {
648
    .convert = { host_to_target_termios, target_to_host_termios },
649
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
650
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
651
};
652

    
653
#ifdef TARGET_I386
654

    
655
/* NOTE: there is really one LDT for all the threads */
656
uint8_t *ldt_table;
657

    
658
static int read_ldt(void *ptr, unsigned long bytecount)
659
{
660
    int size;
661

    
662
    if (!ldt_table)
663
        return 0;
664
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
665
    if (size > bytecount)
666
        size = bytecount;
667
    memcpy(ptr, ldt_table, size);
668
    return size;
669
}
670

    
671
/* XXX: add locking support */
672
static int write_ldt(CPUX86State *env, 
673
                     void *ptr, unsigned long bytecount, int oldmode)
674
{
675
    struct target_modify_ldt_ldt_s ldt_info;
676
    int seg_32bit, contents, read_exec_only, limit_in_pages;
677
    int seg_not_present, useable;
678
    uint32_t *lp, entry_1, entry_2;
679

    
680
    if (bytecount != sizeof(ldt_info))
681
        return -EINVAL;
682
    memcpy(&ldt_info, ptr, sizeof(ldt_info));
683
    tswap32s(&ldt_info.entry_number);
684
    tswapls((long *)&ldt_info.base_addr);
685
    tswap32s(&ldt_info.limit);
686
    tswap32s(&ldt_info.flags);
687
    
688
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
689
        return -EINVAL;
690
    seg_32bit = ldt_info.flags & 1;
691
    contents = (ldt_info.flags >> 1) & 3;
692
    read_exec_only = (ldt_info.flags >> 3) & 1;
693
    limit_in_pages = (ldt_info.flags >> 4) & 1;
694
    seg_not_present = (ldt_info.flags >> 5) & 1;
695
    useable = (ldt_info.flags >> 6) & 1;
696

    
697
    if (contents == 3) {
698
        if (oldmode)
699
            return -EINVAL;
700
        if (seg_not_present == 0)
701
            return -EINVAL;
702
    }
703
    /* allocate the LDT */
704
    if (!ldt_table) {
705
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
706
        if (!ldt_table)
707
            return -ENOMEM;
708
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
709
        env->ldt.base = ldt_table;
710
        env->ldt.limit = 0xffff;
711
    }
712

    
713
    /* NOTE: same code as Linux kernel */
714
    /* Allow LDTs to be cleared by the user. */
715
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
716
        if (oldmode ||
717
            (contents == 0                &&
718
             read_exec_only == 1        &&
719
             seg_32bit == 0                &&
720
             limit_in_pages == 0        &&
721
             seg_not_present == 1        &&
722
             useable == 0 )) {
723
            entry_1 = 0;
724
            entry_2 = 0;
725
            goto install;
726
        }
727
    }
728
    
729
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
730
        (ldt_info.limit & 0x0ffff);
731
    entry_2 = (ldt_info.base_addr & 0xff000000) |
732
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
733
        (ldt_info.limit & 0xf0000) |
734
        ((read_exec_only ^ 1) << 9) |
735
        (contents << 10) |
736
        ((seg_not_present ^ 1) << 15) |
737
        (seg_32bit << 22) |
738
        (limit_in_pages << 23) |
739
        0x7000;
740
    if (!oldmode)
741
        entry_2 |= (useable << 20);
742
    
743
    /* Install the new entry ...  */
744
install:
745
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
746
    lp[0] = tswap32(entry_1);
747
    lp[1] = tswap32(entry_2);
748
    return 0;
749
}
750

    
751
/* specific and weird i386 syscalls */
752
int gemu_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
753
{
754
    int ret = -ENOSYS;
755
    
756
    switch (func) {
757
    case 0:
758
        ret = read_ldt(ptr, bytecount);
759
        break;
760
    case 1:
761
        ret = write_ldt(env, ptr, bytecount, 1);
762
        break;
763
    case 0x11:
764
        ret = write_ldt(env, ptr, bytecount, 0);
765
        break;
766
    }
767
    return ret;
768
}
769
#endif
770

    
771
void syscall_init(void)
772
{
773
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
774
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 
775
#include "syscall_types.h"
776
#undef STRUCT
777
#undef STRUCT_SPECIAL
778
}
779
                                 
780
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 
781
                long arg4, long arg5, long arg6)
782
{
783
    long ret;
784
    struct stat st;
785
    struct kernel_statfs *stfs;
786
    
787
#ifdef DEBUG
788
    gemu_log("syscall %d\n", num);
789
#endif
790
    switch(num) {
791
    case TARGET_NR_exit:
792
#ifdef HAVE_GPROF
793
        _mcleanup();
794
#endif
795
        _exit(arg1);
796
        ret = 0; /* avoid warning */
797
        break;
798
    case TARGET_NR_read:
799
        ret = get_errno(read(arg1, (void *)arg2, arg3));
800
        break;
801
    case TARGET_NR_write:
802
        ret = get_errno(write(arg1, (void *)arg2, arg3));
803
        break;
804
    case TARGET_NR_open:
805
        ret = get_errno(open((const char *)arg1, arg2, arg3));
806
        break;
807
    case TARGET_NR_close:
808
        ret = get_errno(close(arg1));
809
        break;
810
    case TARGET_NR_brk:
811
        ret = do_brk((char *)arg1);
812
        break;
813
    case TARGET_NR_fork:
814
        ret = get_errno(fork());
815
        break;
816
    case TARGET_NR_waitpid:
817
        {
818
            int *status = (int *)arg2;
819
            ret = get_errno(waitpid(arg1, status, arg3));
820
            if (!is_error(ret) && status)
821
                tswapls((long *)&status);
822
        }
823
        break;
824
    case TARGET_NR_creat:
825
        ret = get_errno(creat((const char *)arg1, arg2));
826
        break;
827
    case TARGET_NR_link:
828
        ret = get_errno(link((const char *)arg1, (const char *)arg2));
829
        break;
830
    case TARGET_NR_unlink:
831
        ret = get_errno(unlink((const char *)arg1));
832
        break;
833
    case TARGET_NR_execve:
834
        ret = get_errno(execve((const char *)arg1, (void *)arg2, (void *)arg3));
835
        break;
836
    case TARGET_NR_chdir:
837
        ret = get_errno(chdir((const char *)arg1));
838
        break;
839
    case TARGET_NR_time:
840
        {
841
            int *time_ptr = (int *)arg1;
842
            ret = get_errno(time((time_t *)time_ptr));
843
            if (!is_error(ret) && time_ptr)
844
                tswap32s(time_ptr);
845
        }
846
        break;
847
    case TARGET_NR_mknod:
848
        ret = get_errno(mknod((const char *)arg1, arg2, arg3));
849
        break;
850
    case TARGET_NR_chmod:
851
        ret = get_errno(chmod((const char *)arg1, arg2));
852
        break;
853
    case TARGET_NR_lchown:
854
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
855
        break;
856
    case TARGET_NR_break:
857
        goto unimplemented;
858
    case TARGET_NR_oldstat:
859
        goto unimplemented;
860
    case TARGET_NR_lseek:
861
        ret = get_errno(lseek(arg1, arg2, arg3));
862
        break;
863
    case TARGET_NR_getpid:
864
        ret = get_errno(getpid());
865
        break;
866
    case TARGET_NR_mount:
867
        /* need to look at the data field */
868
        goto unimplemented;
869
    case TARGET_NR_umount:
870
        ret = get_errno(umount((const char *)arg1));
871
        break;
872
    case TARGET_NR_setuid:
873
        ret = get_errno(setuid(arg1));
874
        break;
875
    case TARGET_NR_getuid:
876
        ret = get_errno(getuid());
877
        break;
878
    case TARGET_NR_stime:
879
        {
880
            int *time_ptr = (int *)arg1;
881
            if (time_ptr)
882
                tswap32s(time_ptr);
883
            ret = get_errno(stime((time_t *)time_ptr));
884
        }
885
        break;
886
    case TARGET_NR_ptrace:
887
        goto unimplemented;
888
    case TARGET_NR_alarm:
889
        ret = alarm(arg1);
890
        break;
891
    case TARGET_NR_oldfstat:
892
        goto unimplemented;
893
    case TARGET_NR_pause:
894
        ret = get_errno(pause());
895
        break;
896
    case TARGET_NR_utime:
897
        goto unimplemented;
898
    case TARGET_NR_stty:
899
        goto unimplemented;
900
    case TARGET_NR_gtty:
901
        goto unimplemented;
902
    case TARGET_NR_access:
903
        ret = get_errno(access((const char *)arg1, arg2));
904
        break;
905
    case TARGET_NR_nice:
906
        ret = get_errno(nice(arg1));
907
        break;
908
    case TARGET_NR_ftime:
909
        goto unimplemented;
910
    case TARGET_NR_sync:
911
        sync();
912
        ret = 0;
913
        break;
914
    case TARGET_NR_kill:
915
        ret = get_errno(kill(arg1, arg2));
916
        break;
917
    case TARGET_NR_rename:
918
        ret = get_errno(rename((const char *)arg1, (const char *)arg2));
919
        break;
920
    case TARGET_NR_mkdir:
921
        ret = get_errno(mkdir((const char *)arg1, arg2));
922
        break;
923
    case TARGET_NR_rmdir:
924
        ret = get_errno(rmdir((const char *)arg1));
925
        break;
926
    case TARGET_NR_dup:
927
        ret = get_errno(dup(arg1));
928
        break;
929
    case TARGET_NR_pipe:
930
        {
931
            int *pipe_ptr = (int *)arg1;
932
            ret = get_errno(pipe(pipe_ptr));
933
            if (!is_error(ret)) {
934
                tswap32s(&pipe_ptr[0]);
935
                tswap32s(&pipe_ptr[1]);
936
            }
937
        }
938
        break;
939
    case TARGET_NR_times:
940
        goto unimplemented;
941
    case TARGET_NR_prof:
942
        goto unimplemented;
943
    case TARGET_NR_setgid:
944
        ret = get_errno(setgid(arg1));
945
        break;
946
    case TARGET_NR_getgid:
947
        ret = get_errno(getgid());
948
        break;
949
    case TARGET_NR_signal:
950
        goto unimplemented;
951
    case TARGET_NR_geteuid:
952
        ret = get_errno(geteuid());
953
        break;
954
    case TARGET_NR_getegid:
955
        ret = get_errno(getegid());
956
        break;
957
    case TARGET_NR_acct:
958
        goto unimplemented;
959
    case TARGET_NR_umount2:
960
        ret = get_errno(umount2((const char *)arg1, arg2));
961
        break;
962
    case TARGET_NR_lock:
963
        goto unimplemented;
964
    case TARGET_NR_ioctl:
965
        ret = do_ioctl(arg1, arg2, arg3);
966
        break;
967
    case TARGET_NR_fcntl:
968
        switch(arg2) {
969
        case F_GETLK:
970
        case F_SETLK:
971
        case F_SETLKW:
972
            goto unimplemented;
973
        default:
974
            ret = get_errno(fcntl(arg1, arg2, arg3));
975
            break;
976
        }
977
        break;
978
    case TARGET_NR_mpx:
979
        goto unimplemented;
980
    case TARGET_NR_setpgid:
981
        ret = get_errno(setpgid(arg1, arg2));
982
        break;
983
    case TARGET_NR_ulimit:
984
        goto unimplemented;
985
    case TARGET_NR_oldolduname:
986
        goto unimplemented;
987
    case TARGET_NR_umask:
988
        ret = get_errno(umask(arg1));
989
        break;
990
    case TARGET_NR_chroot:
991
        ret = get_errno(chroot((const char *)arg1));
992
        break;
993
    case TARGET_NR_ustat:
994
        goto unimplemented;
995
    case TARGET_NR_dup2:
996
        ret = get_errno(dup2(arg1, arg2));
997
        break;
998
    case TARGET_NR_getppid:
999
        ret = get_errno(getppid());
1000
        break;
1001
    case TARGET_NR_getpgrp:
1002
        ret = get_errno(getpgrp());
1003
        break;
1004
    case TARGET_NR_setsid:
1005
        ret = get_errno(setsid());
1006
        break;
1007
    case TARGET_NR_sigaction:
1008
#if 0
1009
        {
1010
            ret = 0;
1011
        }
1012
        break;
1013
#else
1014
        goto unimplemented;
1015
#endif
1016
    case TARGET_NR_sgetmask:
1017
        goto unimplemented;
1018
    case TARGET_NR_ssetmask:
1019
        goto unimplemented;
1020
    case TARGET_NR_setreuid:
1021
        ret = get_errno(setreuid(arg1, arg2));
1022
        break;
1023
    case TARGET_NR_setregid:
1024
        ret = get_errno(setregid(arg1, arg2));
1025
        break;
1026
    case TARGET_NR_sigsuspend:
1027
        goto unimplemented;
1028
    case TARGET_NR_sigpending:
1029
        goto unimplemented;
1030
    case TARGET_NR_sethostname:
1031
        ret = get_errno(sethostname((const char *)arg1, arg2));
1032
        break;
1033
    case TARGET_NR_setrlimit:
1034
        goto unimplemented;
1035
    case TARGET_NR_getrlimit:
1036
        goto unimplemented;
1037
    case TARGET_NR_getrusage:
1038
        goto unimplemented;
1039
    case TARGET_NR_gettimeofday:
1040
        {
1041
            struct target_timeval *target_tv = (void *)arg1;
1042
            struct timeval tv;
1043
            ret = get_errno(gettimeofday(&tv, NULL));
1044
            if (!is_error(ret)) {
1045
                target_tv->tv_sec = tswapl(tv.tv_sec);
1046
                target_tv->tv_usec = tswapl(tv.tv_usec);
1047
            }
1048
        }
1049
        break;
1050
    case TARGET_NR_settimeofday:
1051
        {
1052
            struct target_timeval *target_tv = (void *)arg1;
1053
            struct timeval tv;
1054
            tv.tv_sec = tswapl(target_tv->tv_sec);
1055
            tv.tv_usec = tswapl(target_tv->tv_usec);
1056
            ret = get_errno(settimeofday(&tv, NULL));
1057
        }
1058
        break;
1059
    case TARGET_NR_getgroups:
1060
        goto unimplemented;
1061
    case TARGET_NR_setgroups:
1062
        goto unimplemented;
1063
    case TARGET_NR_select:
1064
        goto unimplemented;
1065
    case TARGET_NR_symlink:
1066
        ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
1067
        break;
1068
    case TARGET_NR_oldlstat:
1069
        goto unimplemented;
1070
    case TARGET_NR_readlink:
1071
        ret = get_errno(readlink((const char *)arg1, (char *)arg2, arg3));
1072
        break;
1073
    case TARGET_NR_uselib:
1074
        goto unimplemented;
1075
    case TARGET_NR_swapon:
1076
        ret = get_errno(swapon((const char *)arg1, arg2));
1077
        break;
1078
    case TARGET_NR_reboot:
1079
        goto unimplemented;
1080
    case TARGET_NR_readdir:
1081
        goto unimplemented;
1082
#ifdef TARGET_I386
1083
    case TARGET_NR_mmap:
1084
        {
1085
            uint32_t v1, v2, v3, v4, v5, v6, *vptr;
1086
            vptr = (uint32_t *)arg1;
1087
            v1 = tswap32(vptr[0]);
1088
            v2 = tswap32(vptr[1]);
1089
            v3 = tswap32(vptr[2]);
1090
            v4 = tswap32(vptr[3]);
1091
            v5 = tswap32(vptr[4]);
1092
            v6 = tswap32(vptr[5]);
1093
            ret = get_errno((long)mmap((void *)v1, v2, v3, v4, v5, v6));
1094
        }
1095
        break;
1096
#endif
1097
#ifdef TARGET_I386
1098
    case TARGET_NR_mmap2:
1099
#else
1100
    case TARGET_NR_mmap:
1101
#endif
1102
        ret = get_errno((long)mmap((void *)arg1, arg2, arg3, arg4, arg5, arg6));
1103
        break;
1104
    case TARGET_NR_munmap:
1105
        ret = get_errno(munmap((void *)arg1, arg2));
1106
        break;
1107
    case TARGET_NR_truncate:
1108
        ret = get_errno(truncate((const char *)arg1, arg2));
1109
        break;
1110
    case TARGET_NR_ftruncate:
1111
        ret = get_errno(ftruncate(arg1, arg2));
1112
        break;
1113
    case TARGET_NR_fchmod:
1114
        ret = get_errno(fchmod(arg1, arg2));
1115
        break;
1116
    case TARGET_NR_fchown:
1117
        ret = get_errno(fchown(arg1, arg2, arg3));
1118
        break;
1119
    case TARGET_NR_getpriority:
1120
        ret = get_errno(getpriority(arg1, arg2));
1121
        break;
1122
    case TARGET_NR_setpriority:
1123
        ret = get_errno(setpriority(arg1, arg2, arg3));
1124
        break;
1125
    case TARGET_NR_profil:
1126
        goto unimplemented;
1127
    case TARGET_NR_statfs:
1128
        stfs = (void *)arg2;
1129
        ret = get_errno(sys_statfs((const char *)arg1, stfs));
1130
    convert_statfs:
1131
        if (!is_error(ret)) {
1132
            tswap32s(&stfs->f_type);
1133
            tswap32s(&stfs->f_bsize);
1134
            tswap32s(&stfs->f_blocks);
1135
            tswap32s(&stfs->f_bfree);
1136
            tswap32s(&stfs->f_bavail);
1137
            tswap32s(&stfs->f_files);
1138
            tswap32s(&stfs->f_ffree);
1139
            tswap32s(&stfs->f_fsid.val[0]);
1140
            tswap32s(&stfs->f_fsid.val[1]);
1141
            tswap32s(&stfs->f_namelen);
1142
        }
1143
        break;
1144
    case TARGET_NR_fstatfs:
1145
        stfs = (void *)arg2;
1146
        ret = get_errno(sys_fstatfs(arg1, stfs));
1147
        goto convert_statfs;
1148
    case TARGET_NR_ioperm:
1149
        goto unimplemented;
1150
    case TARGET_NR_socketcall:
1151
        ret = do_socketcall(arg1, (long *)arg2);
1152
        break;
1153
    case TARGET_NR_syslog:
1154
        goto unimplemented;
1155
    case TARGET_NR_setitimer:
1156
        goto unimplemented;
1157
    case TARGET_NR_getitimer:
1158
        goto unimplemented;
1159
    case TARGET_NR_stat:
1160
        ret = get_errno(stat((const char *)arg1, &st));
1161
        goto do_stat;
1162
    case TARGET_NR_lstat:
1163
        ret = get_errno(lstat((const char *)arg1, &st));
1164
        goto do_stat;
1165
    case TARGET_NR_fstat:
1166
        {
1167
            ret = get_errno(fstat(arg1, &st));
1168
        do_stat:
1169
            if (!is_error(ret)) {
1170
                struct target_stat *target_st = (void *)arg2;
1171
                target_st->st_dev = tswap16(st.st_dev);
1172
                target_st->st_ino = tswapl(st.st_ino);
1173
                target_st->st_mode = tswap16(st.st_mode);
1174
                target_st->st_nlink = tswap16(st.st_nlink);
1175
                target_st->st_uid = tswap16(st.st_uid);
1176
                target_st->st_gid = tswap16(st.st_gid);
1177
                target_st->st_rdev = tswap16(st.st_rdev);
1178
                target_st->st_size = tswapl(st.st_size);
1179
                target_st->st_blksize = tswapl(st.st_blksize);
1180
                target_st->st_blocks = tswapl(st.st_blocks);
1181
                target_st->st_atime = tswapl(st.st_atime);
1182
                target_st->st_mtime = tswapl(st.st_mtime);
1183
                target_st->st_ctime = tswapl(st.st_ctime);
1184
            }
1185
        }
1186
        break;
1187
    case TARGET_NR_olduname:
1188
        goto unimplemented;
1189
    case TARGET_NR_iopl:
1190
        goto unimplemented;
1191
    case TARGET_NR_vhangup:
1192
        ret = get_errno(vhangup());
1193
        break;
1194
    case TARGET_NR_idle:
1195
        goto unimplemented;
1196
    case TARGET_NR_vm86old:
1197
        goto unimplemented;
1198
    case TARGET_NR_wait4:
1199
        {
1200
            int status;
1201
            target_long *status_ptr = (void *)arg2;
1202
            struct rusage rusage, *rusage_ptr;
1203
            struct target_rusage *target_rusage = (void *)arg4;
1204
            if (target_rusage)
1205
                rusage_ptr = &rusage;
1206
            else
1207
                rusage_ptr = NULL;
1208
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
1209
            if (!is_error(ret)) {
1210
                if (status_ptr)
1211
                    *status_ptr = tswap32(status);
1212
                if (target_rusage) {
1213
                    target_rusage->ru_utime.tv_sec = tswapl(rusage.ru_utime.tv_sec);
1214
                    target_rusage->ru_utime.tv_usec = tswapl(rusage.ru_utime.tv_usec);
1215
                    target_rusage->ru_stime.tv_sec = tswapl(rusage.ru_stime.tv_sec);
1216
                    target_rusage->ru_stime.tv_usec = tswapl(rusage.ru_stime.tv_usec);
1217
                    target_rusage->ru_maxrss = tswapl(rusage.ru_maxrss);
1218
                    target_rusage->ru_ixrss = tswapl(rusage.ru_ixrss);
1219
                    target_rusage->ru_idrss = tswapl(rusage.ru_idrss);
1220
                    target_rusage->ru_isrss = tswapl(rusage.ru_isrss);
1221
                    target_rusage->ru_minflt = tswapl(rusage.ru_minflt);
1222
                    target_rusage->ru_majflt = tswapl(rusage.ru_majflt);
1223
                    target_rusage->ru_nswap = tswapl(rusage.ru_nswap);
1224
                    target_rusage->ru_inblock = tswapl(rusage.ru_inblock);
1225
                    target_rusage->ru_oublock = tswapl(rusage.ru_oublock);
1226
                    target_rusage->ru_msgsnd = tswapl(rusage.ru_msgsnd);
1227
                    target_rusage->ru_msgrcv = tswapl(rusage.ru_msgrcv);
1228
                    target_rusage->ru_nsignals = tswapl(rusage.ru_nsignals);
1229
                    target_rusage->ru_nvcsw = tswapl(rusage.ru_nvcsw);
1230
                    target_rusage->ru_nivcsw = tswapl(rusage.ru_nivcsw);
1231
                }
1232
            }
1233
        }
1234
        break;
1235
    case TARGET_NR_swapoff:
1236
        ret = get_errno(swapoff((const char *)arg1));
1237
        break;
1238
    case TARGET_NR_sysinfo:
1239
        goto unimplemented;
1240
    case TARGET_NR_ipc:
1241
        goto unimplemented;
1242
    case TARGET_NR_fsync:
1243
        ret = get_errno(fsync(arg1));
1244
        break;
1245
    case TARGET_NR_sigreturn:
1246
        goto unimplemented;
1247
    case TARGET_NR_clone:
1248
        goto unimplemented;
1249
    case TARGET_NR_setdomainname:
1250
        ret = get_errno(setdomainname((const char *)arg1, arg2));
1251
        break;
1252
    case TARGET_NR_uname:
1253
        /* no need to transcode because we use the linux syscall */
1254
        ret = get_errno(sys_uname((struct new_utsname *)arg1));
1255
        break;
1256
#ifdef TARGET_I386
1257
    case TARGET_NR_modify_ldt:
1258
        ret = get_errno(gemu_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
1259
        break;
1260
#endif
1261
    case TARGET_NR_adjtimex:
1262
        goto unimplemented;
1263
    case TARGET_NR_mprotect:
1264
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1265
        break;
1266
    case TARGET_NR_sigprocmask:
1267
        {
1268
            int how = arg1;
1269
            sigset_t set, oldset, *set_ptr;
1270
            target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
1271
            
1272
            switch(how) {
1273
            case TARGET_SIG_BLOCK:
1274
                how = SIG_BLOCK;
1275
                break;
1276
            case TARGET_SIG_UNBLOCK:
1277
                how = SIG_UNBLOCK;
1278
                break;
1279
            case TARGET_SIG_SETMASK:
1280
                how = SIG_SETMASK;
1281
                break;
1282
            default:
1283
                ret = -EINVAL;
1284
                goto fail;
1285
            }
1286
            
1287
            if (pset) {
1288
                target_to_host_old_sigset(&set, pset);
1289
                set_ptr = &set;
1290
            } else {
1291
                set_ptr = NULL;
1292
            }
1293
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1294
            if (!is_error(ret) && poldset) {
1295
                host_to_target_old_sigset(poldset, &oldset);
1296
            }
1297
        }
1298
        break;
1299
    case TARGET_NR_create_module:
1300
    case TARGET_NR_init_module:
1301
    case TARGET_NR_delete_module:
1302
    case TARGET_NR_get_kernel_syms:
1303
        goto unimplemented;
1304
    case TARGET_NR_quotactl:
1305
        goto unimplemented;
1306
    case TARGET_NR_getpgid:
1307
        ret = get_errno(getpgid(arg1));
1308
        break;
1309
    case TARGET_NR_fchdir:
1310
        ret = get_errno(fchdir(arg1));
1311
        break;
1312
    case TARGET_NR_bdflush:
1313
        goto unimplemented;
1314
    case TARGET_NR_sysfs:
1315
        goto unimplemented;
1316
    case TARGET_NR_personality:
1317
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1318
        break;
1319
    case TARGET_NR_afs_syscall:
1320
        goto unimplemented;
1321
    case TARGET_NR_setfsuid:
1322
        goto unimplemented;
1323
    case TARGET_NR_setfsgid:
1324
        goto unimplemented;
1325
    case TARGET_NR__llseek:
1326
        {
1327
            int64_t res;
1328
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
1329
            *(int64_t *)arg4 = tswap64(res);
1330
        }
1331
        break;
1332
    case TARGET_NR_getdents:
1333
#if TARGET_LONG_SIZE != 4
1334
#error not supported
1335
#endif
1336
        {
1337
            struct dirent *dirp = (void *)arg2;
1338
            long count = arg3;
1339
            ret = get_errno(sys_getdents(arg1, dirp, count));
1340
            if (!is_error(ret)) {
1341
                struct dirent *de;
1342
                int len = ret;
1343
                int reclen;
1344
                de = dirp;
1345
                while (len > 0) {
1346
                    reclen = tswap16(de->d_reclen);
1347
                    if (reclen > len)
1348
                        break;
1349
                    de->d_reclen = reclen;
1350
                    tswapls(&de->d_ino);
1351
                    tswapls(&de->d_off);
1352
                    de = (struct dirent *)((char *)de + reclen);
1353
                    len -= reclen;
1354
                }
1355
            }
1356
        }
1357
        break;
1358
    case TARGET_NR__newselect:
1359
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
1360
                        (void *)arg5);
1361
        break;
1362
    case TARGET_NR_flock:
1363
        goto unimplemented;
1364
    case TARGET_NR_msync:
1365
        ret = get_errno(msync((void *)arg1, arg2, arg3));
1366
        break;
1367
    case TARGET_NR_readv:
1368
        {
1369
            int count = arg3;
1370
            int i;
1371
            struct iovec *vec;
1372
            struct target_iovec *target_vec = (void *)arg2;
1373

    
1374
            vec = alloca(count * sizeof(struct iovec));
1375
            for(i = 0;i < count; i++) {
1376
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1377
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
1378
            }
1379
            ret = get_errno(readv(arg1, vec, count));
1380
        }
1381
        break;
1382
    case TARGET_NR_writev:
1383
        {
1384
            int count = arg3;
1385
            int i;
1386
            struct iovec *vec;
1387
            struct target_iovec *target_vec = (void *)arg2;
1388

    
1389
            vec = alloca(count * sizeof(struct iovec));
1390
            for(i = 0;i < count; i++) {
1391
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1392
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
1393
            }
1394
            ret = get_errno(writev(arg1, vec, count));
1395
        }
1396
        break;
1397
    case TARGET_NR_getsid:
1398
        ret = get_errno(getsid(arg1));
1399
        break;
1400
    case TARGET_NR_fdatasync:
1401
        goto unimplemented;
1402
    case TARGET_NR__sysctl:
1403
        goto unimplemented;
1404
    case TARGET_NR_mlock:
1405
        ret = get_errno(mlock((void *)arg1, arg2));
1406
        break;
1407
    case TARGET_NR_munlock:
1408
        ret = get_errno(munlock((void *)arg1, arg2));
1409
        break;
1410
    case TARGET_NR_mlockall:
1411
        ret = get_errno(mlockall(arg1));
1412
        break;
1413
    case TARGET_NR_munlockall:
1414
        ret = get_errno(munlockall());
1415
        break;
1416
    case TARGET_NR_sched_setparam:
1417
        goto unimplemented;
1418
    case TARGET_NR_sched_getparam:
1419
        goto unimplemented;
1420
    case TARGET_NR_sched_setscheduler:
1421
        goto unimplemented;
1422
    case TARGET_NR_sched_getscheduler:
1423
        goto unimplemented;
1424
    case TARGET_NR_sched_yield:
1425
        ret = get_errno(sched_yield());
1426
        break;
1427
    case TARGET_NR_sched_get_priority_max:
1428
    case TARGET_NR_sched_get_priority_min:
1429
    case TARGET_NR_sched_rr_get_interval:
1430
    case TARGET_NR_nanosleep:
1431
    case TARGET_NR_mremap:
1432
    case TARGET_NR_setresuid:
1433
    case TARGET_NR_getresuid:
1434
    case TARGET_NR_vm86:
1435
    case TARGET_NR_query_module:
1436
    case TARGET_NR_poll:
1437
    case TARGET_NR_nfsservctl:
1438
    case TARGET_NR_setresgid:
1439
    case TARGET_NR_getresgid:
1440
    case TARGET_NR_prctl:
1441
    case TARGET_NR_rt_sigreturn:
1442
    case TARGET_NR_rt_sigaction:
1443
    case TARGET_NR_rt_sigprocmask:
1444
    case TARGET_NR_rt_sigpending:
1445
    case TARGET_NR_rt_sigtimedwait:
1446
    case TARGET_NR_rt_sigqueueinfo:
1447
    case TARGET_NR_rt_sigsuspend:
1448
    case TARGET_NR_pread:
1449
    case TARGET_NR_pwrite:
1450
        goto unimplemented;
1451
    case TARGET_NR_chown:
1452
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
1453
        break;
1454
    case TARGET_NR_getcwd:
1455
        ret = get_errno(sys_getcwd1((char *)arg1, arg2));
1456
        break;
1457
    case TARGET_NR_capget:
1458
    case TARGET_NR_capset:
1459
    case TARGET_NR_sigaltstack:
1460
    case TARGET_NR_sendfile:
1461
    case TARGET_NR_getpmsg:
1462
    case TARGET_NR_putpmsg:
1463
    case TARGET_NR_vfork:
1464
        ret = get_errno(vfork());
1465
        break;
1466
    case TARGET_NR_ugetrlimit:
1467
    case TARGET_NR_truncate64:
1468
    case TARGET_NR_ftruncate64:
1469
        goto unimplemented;
1470
    case TARGET_NR_stat64:
1471
        ret = get_errno(stat((const char *)arg1, &st));
1472
        goto do_stat64;
1473
    case TARGET_NR_lstat64:
1474
        ret = get_errno(lstat((const char *)arg1, &st));
1475
        goto do_stat64;
1476
    case TARGET_NR_fstat64:
1477
        {
1478
            ret = get_errno(fstat(arg1, &st));
1479
        do_stat64:
1480
            if (!is_error(ret)) {
1481
                struct target_stat64 *target_st = (void *)arg2;
1482
                target_st->st_dev = tswap16(st.st_dev);
1483
                target_st->st_ino = tswapl(st.st_ino);
1484
                target_st->st_mode = tswap16(st.st_mode);
1485
                target_st->st_nlink = tswap16(st.st_nlink);
1486
                target_st->st_uid = tswap16(st.st_uid);
1487
                target_st->st_gid = tswap16(st.st_gid);
1488
                target_st->st_rdev = tswap16(st.st_rdev);
1489
                /* XXX: better use of kernel struct */
1490
                target_st->st_size = tswapl(st.st_size);
1491
                target_st->st_blksize = tswapl(st.st_blksize);
1492
                target_st->st_blocks = tswapl(st.st_blocks);
1493
                target_st->st_atime = tswapl(st.st_atime);
1494
                target_st->st_mtime = tswapl(st.st_mtime);
1495
                target_st->st_ctime = tswapl(st.st_ctime);
1496
            }
1497
        }
1498
        break;
1499

    
1500
    case TARGET_NR_lchown32:
1501
    case TARGET_NR_getuid32:
1502
    case TARGET_NR_getgid32:
1503
    case TARGET_NR_geteuid32:
1504
    case TARGET_NR_getegid32:
1505
    case TARGET_NR_setreuid32:
1506
    case TARGET_NR_setregid32:
1507
    case TARGET_NR_getgroups32:
1508
    case TARGET_NR_setgroups32:
1509
    case TARGET_NR_fchown32:
1510
    case TARGET_NR_setresuid32:
1511
    case TARGET_NR_getresuid32:
1512
    case TARGET_NR_setresgid32:
1513
    case TARGET_NR_getresgid32:
1514
    case TARGET_NR_chown32:
1515
    case TARGET_NR_setuid32:
1516
    case TARGET_NR_setgid32:
1517
    case TARGET_NR_setfsuid32:
1518
    case TARGET_NR_setfsgid32:
1519
    case TARGET_NR_pivot_root:
1520
    case TARGET_NR_mincore:
1521
    case TARGET_NR_madvise:
1522
    case TARGET_NR_getdents64:
1523
        goto unimplemented;
1524
#if TARGET_LONG_BITS == 32
1525
    case TARGET_NR_fcntl64:
1526
        switch(arg2) {
1527
        case F_GETLK64:
1528
        case F_SETLK64:
1529
        case F_SETLKW64:
1530
            goto unimplemented;
1531
        default:
1532
            ret = get_errno(fcntl(arg1, arg2, arg3));
1533
            break;
1534
        }
1535
        break;
1536
#endif
1537
    case TARGET_NR_security:
1538
        goto unimplemented;
1539
    case TARGET_NR_gettid:
1540
        ret = get_errno(gettid());
1541
        break;
1542
    case TARGET_NR_readahead:
1543
    case TARGET_NR_setxattr:
1544
    case TARGET_NR_lsetxattr:
1545
    case TARGET_NR_fsetxattr:
1546
    case TARGET_NR_getxattr:
1547
    case TARGET_NR_lgetxattr:
1548
    case TARGET_NR_fgetxattr:
1549
    case TARGET_NR_listxattr:
1550
    case TARGET_NR_llistxattr:
1551
    case TARGET_NR_flistxattr:
1552
    case TARGET_NR_removexattr:
1553
    case TARGET_NR_lremovexattr:
1554
    case TARGET_NR_fremovexattr:
1555
        goto unimplemented;
1556
    default:
1557
    unimplemented:
1558
        gemu_log("Unsupported syscall: %d\n", num);
1559
        ret = -ENOSYS;
1560
        break;
1561
    }
1562
 fail:
1563
    return ret;
1564
}
1565