Annotation of qemu/darwin-user/syscall.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Darwin syscalls
                      3:  *
                      4:  *  Copyright (c) 2003 Fabrice Bellard
                      5:  *  Copyright (c) 2006 Pierre d'Herbemont
                      6:  *
                      7:  *  This program is free software; you can redistribute it and/or modify
                      8:  *  it under the terms of the GNU General Public License as published by
                      9:  *  the Free Software Foundation; either version 2 of the License, or
                     10:  *  (at your option) any later version.
                     11:  *
                     12:  *  This program is distributed in the hope that it will be useful,
                     13:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:  *  GNU General Public License for more details.
                     16:  *
                     17:  *  You should have received a copy of the GNU General Public License
                     18:  *  along with this program; if not, write to the Free Software
                     19:  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20:  */
                     21: #include <fcntl.h>
                     22: #include <stdio.h>
                     23: #include <stdlib.h>
                     24: #include <errno.h>
                     25: 
                     26: #include <mach/host_info.h>
                     27: #include <mach/mach.h>
                     28: #include <mach/mach_time.h>
                     29: #include <mach/message.h>
                     30: 
                     31: #include <pthread.h>
                     32: #include <dirent.h>
                     33: 
                     34: #include <sys/stat.h>
                     35: #include <sys/syscall.h>
                     36: #include <sys/sysctl.h>
                     37: #include <sys/types.h>
                     38: #include <unistd.h>
                     39: #include <sys/ioctl.h>
                     40: #include <sys/mman.h>
                     41: #include <sys/types.h>
                     42: #include <sys/dirent.h>
                     43: #include <sys/uio.h>
                     44: #include <sys/termios.h>
                     45: #include <sys/ptrace.h>
                     46: #include <net/if.h>
                     47: 
                     48: #include <sys/param.h>
                     49: #include <sys/mount.h>
                     50: 
                     51: #include <sys/attr.h>
                     52: 
                     53: #include <mach/ndr.h>
                     54: #include <mach/mig_errors.h>
                     55: 
                     56: #include "qemu.h"
                     57: 
                     58: //#define DEBUG_SYSCALL
                     59: 
                     60: #ifdef DEBUG_SYSCALL
                     61: # define DEBUG_FORCE_ENABLE_LOCAL() int __DEBUG_qemu_user_force_enable = 1
                     62: # define DEBUG_BEGIN_ENABLE  __DEBUG_qemu_user_force_enable = 1;
                     63: # define DEBUG_END_ENABLE  __DEBUG_qemu_user_force_enable = 0;
                     64: 
                     65: # define DEBUG_DISABLE_ALL() static int __DEBUG_qemu_user_force_enable = 0
                     66: # define DEBUG_ENABLE_ALL()  static int __DEBUG_qemu_user_force_enable = 1
                     67:     DEBUG_ENABLE_ALL();
                     68: 
                     69: # define DPRINTF(...) do { if(loglevel) fprintf(logfile, __VA_ARGS__); \
                     70:                            if(__DEBUG_qemu_user_force_enable) fprintf(stderr, __VA_ARGS__); \
                     71:                          } while(0)
                     72: #else
                     73: # define DEBUG_FORCE_ENABLE_LOCAL()
                     74: # define DEBUG_BEGIN_ENABLE
                     75: # define DEBUG_END_ENABLE
                     76: 
                     77: # define DPRINTF(...) do { if(loglevel) fprintf(logfile, __VA_ARGS__); } while(0)
                     78: #endif
                     79: 
                     80: enum {
                     81:     bswap_out = 0,
                     82:     bswap_in = 1
                     83: };
                     84: 
                     85: extern const char *interp_prefix;
                     86: 
                     87: static inline long get_errno(long ret)
                     88: {
                     89:     if (ret == -1)
                     90:         return -errno;
                     91:     else
                     92:         return ret;
                     93: }
                     94: 
                     95: static inline int is_error(long ret)
                     96: {
                     97:     return (unsigned long)ret >= (unsigned long)(-4096);
                     98: }
                     99: 
                    100: /* ------------------------------------------------------------
                    101:    Mach syscall handling
                    102: */
                    103: 
                    104: void static inline print_description_msg_header(mach_msg_header_t *hdr)
                    105: {
                    106:     char *name = NULL;
                    107:     int i;
                    108:     struct { int number; char *name; } msg_name[] =
                    109:     {
                    110:         /* see http://fxr.watson.org/fxr/source/compat/mach/mach_namemap.c?v=NETBSD */
                    111:         { 200,      "host_info" },
                    112:         { 202,      "host_page_size" },
                    113:         { 206,      "host_get_clock_service" },
                    114:         { 206,      "host_get_clock_service" },
                    115:         { 206,      "host_get_clock_service" },
                    116:         { 306,      "host_get_clock_service" },
                    117:         { 3204,     "mach_port_allocate" },
                    118:         { 3206,     "mach_port_deallocate" },
                    119:         { 3404,     "mach_ports_lookup" },
                    120:         { 3409,     "mach_task_get_special_port" },
                    121:         { 3414,     "mach_task_get_exception_ports" },
                    122:         { 3418,     "mach_semaphore_create" },
                    123:         { 3504,     "mach_semaphore_create" },
                    124:         { 3509,     "mach_semaphore_create" },
                    125:         { 3518,     "semaphore_create" },
                    126:         { 3616,     "thread_policy" },
                    127:         { 3801,     "vm_allocate" },
                    128:         { 3802,     "vm_deallocate" },
                    129:         { 3802,     "vm_deallocate" },
                    130:         { 3803,     "vm_protect" },
                    131:         { 3812,     "vm_map" },
                    132:         { 4241776,  "lu_message_send_id" },  /* lookupd */
                    133:         { 4241876,  "lu_message_reply_id" }, /* lookupd */
                    134:     };
                    135: 
                    136:     for(i = 0; i < sizeof(msg_name)/sizeof(msg_name[0]); i++) {
                    137:         if(msg_name[i].number == hdr->msgh_id)
                    138:         {
                    139:             name = msg_name[i].name;
                    140:             break;
                    141:         }
                    142:     }
                    143:     if(!name)
                    144:         DPRINTF("unknown mach msg %d 0x%x\n", hdr->msgh_id, hdr->msgh_id);
                    145:     else
                    146:         DPRINTF("%s\n", name);
                    147: #if 0
                    148:     DPRINTF("Bits: %8x\n", hdr->msgh_bits);
                    149:     DPRINTF("Size: %8x\n", hdr->msgh_size);
                    150:     DPRINTF("Rmte: %8x\n", hdr->msgh_remote_port);
                    151:     DPRINTF("Locl: %8x\n", hdr->msgh_local_port);
                    152:     DPRINTF("Rsrv: %8x\n", hdr->msgh_reserved);
                    153: 
                    154:     DPRINTF("Id  : %8x\n", hdr->msgh_id);
                    155: 
                    156:     NDR_record_t *ndr = (NDR_record_t *)(hdr + 1);
                    157:     DPRINTF("hdr = %p, sizeof(hdr) = %x, NDR = %p\n", hdr, (unsigned int)sizeof(mach_msg_header_t), ndr);
                    158:     DPRINTF("%d %d %d %d %d %d %d %d\n",
                    159:            ndr->mig_vers, ndr->if_vers, ndr->reserved1, ndr->mig_encoding,
                    160:            ndr->int_rep, ndr->char_rep, ndr->float_rep, ndr->reserved2);
                    161: #endif
                    162: }
                    163: 
                    164: static inline void print_mach_msg_return(mach_msg_return_t ret)
                    165: {
                    166:     int i, found = 0;
                    167: #define MACH_MSG_RET(msg) { msg, #msg }
                    168:     struct { int code; char *name; } msg_name[] =
                    169:     {
                    170:         /* ref: http://darwinsource.opendarwin.org/10.4.2/xnu-792.2.4/osfmk/man/mach_msg.html */
                    171:         /* send message */
                    172:         MACH_MSG_RET(MACH_SEND_MSG_TOO_SMALL),
                    173:         MACH_MSG_RET(MACH_SEND_NO_BUFFER),
                    174:         MACH_MSG_RET(MACH_SEND_INVALID_DATA),
                    175:         MACH_MSG_RET(MACH_SEND_INVALID_HEADER),
                    176:         MACH_MSG_RET(MACH_SEND_INVALID_DEST),
                    177:         MACH_MSG_RET(MACH_SEND_INVALID_NOTIFY),
                    178:         MACH_MSG_RET(MACH_SEND_INVALID_REPLY),
                    179:         MACH_MSG_RET(MACH_SEND_INVALID_TRAILER),
                    180:         MACH_MSG_RET(MACH_SEND_INVALID_MEMORY),
                    181:         MACH_MSG_RET(MACH_SEND_INVALID_RIGHT),
                    182:         MACH_MSG_RET(MACH_SEND_INVALID_TYPE),
                    183:         MACH_MSG_RET(MACH_SEND_INTERRUPTED),
                    184:         MACH_MSG_RET(MACH_SEND_TIMED_OUT),
                    185: 
                    186:         MACH_MSG_RET(MACH_RCV_BODY_ERROR),
                    187:         MACH_MSG_RET(MACH_RCV_HEADER_ERROR),
                    188: 
                    189:         MACH_MSG_RET(MACH_RCV_IN_SET),
                    190:         MACH_MSG_RET(MACH_RCV_INTERRUPTED),
                    191: 
                    192:         MACH_MSG_RET(MACH_RCV_INVALID_DATA),
                    193:         MACH_MSG_RET(MACH_RCV_INVALID_NAME),
                    194:         MACH_MSG_RET(MACH_RCV_INVALID_NOTIFY),
                    195:         MACH_MSG_RET(MACH_RCV_INVALID_TRAILER),
                    196:         MACH_MSG_RET(MACH_RCV_INVALID_TYPE),
                    197: 
                    198:         MACH_MSG_RET(MACH_RCV_PORT_CHANGED),
                    199:         MACH_MSG_RET(MACH_RCV_PORT_DIED),
                    200: 
                    201:         MACH_MSG_RET(MACH_RCV_SCATTER_SMALL),
                    202:         MACH_MSG_RET(MACH_RCV_TIMED_OUT),
                    203:         MACH_MSG_RET(MACH_RCV_TOO_LARGE)
                    204:     };
                    205: #undef MACH_MSG_RET
                    206: 
                    207:     if( ret == MACH_MSG_SUCCESS)
                    208:         DPRINTF("MACH_MSG_SUCCESS\n");
                    209:     else
                    210:     {
                    211:         for( i = 0; i < sizeof(msg_name)/sizeof(msg_name[0]); i++) {
                    212:             if(msg_name[i].code == ret) {
                    213:                 DPRINTF("%s\n", msg_name[i].name);
                    214:                 found = 1;
                    215:                 break;
                    216:             }
                    217:         }
                    218:         if(!found)
                    219:             qerror("unknow mach message ret code %d\n", ret);
                    220:     }
                    221: }
                    222: 
                    223: static inline void swap_mach_msg_header(mach_msg_header_t *hdr)
                    224: {
                    225:     hdr->msgh_bits = tswap32(hdr->msgh_bits);
                    226:     hdr->msgh_size = tswap32(hdr->msgh_size);
                    227:     hdr->msgh_remote_port = tswap32(hdr->msgh_remote_port);
                    228:     hdr->msgh_local_port = tswap32(hdr->msgh_local_port);
                    229:     hdr->msgh_reserved = tswap32(hdr->msgh_reserved);
                    230:     hdr->msgh_id = tswap32(hdr->msgh_id);
                    231: }
                    232: 
                    233: struct complex_msg {
                    234:             mach_msg_header_t hdr;
                    235:             mach_msg_body_t body;
                    236: };
                    237: 
                    238: static inline void swap_mach_msg_body(struct complex_msg *complex_msg, int bswap)
                    239: {
                    240:     mach_msg_port_descriptor_t *descr = (mach_msg_port_descriptor_t *)(complex_msg+1);
                    241:     int i,j;
                    242: 
                    243:     if(bswap == bswap_in)
                    244:         tswap32s(&complex_msg->body.msgh_descriptor_count);
                    245: 
                    246:     DPRINTF("body.msgh_descriptor_count %d\n", complex_msg->body.msgh_descriptor_count);
                    247: 
                    248:     for(i = 0; i < complex_msg->body.msgh_descriptor_count; i++) {
                    249:         switch(descr->type)
                    250:         {
                    251:             case MACH_MSG_PORT_DESCRIPTOR:
                    252:                 tswap32s(&descr->name);
                    253:                 descr++;
                    254:                 break;
                    255:             case MACH_MSG_OOL_DESCRIPTOR:
                    256:             {
                    257:                 mach_msg_ool_descriptor_t *ool = (void *)descr;
                    258:                 tswap32s((uint32_t *)&ool->address);
                    259:                 tswap32s(&ool->size);
                    260: 
                    261:                 descr = (mach_msg_port_descriptor_t *)(ool+1);
                    262:                 break;
                    263:             }
                    264:             case MACH_MSG_OOL_PORTS_DESCRIPTOR:
                    265:             {
                    266:                 mach_msg_ool_ports_descriptor_t *ool_ports = (void *)descr;
                    267:                 mach_port_name_t * port_names;
                    268: 
                    269:                 if(bswap == bswap_in)
                    270:                 {
                    271:                     tswap32s((uint32_t *)&ool_ports->address);
                    272:                     tswap32s(&ool_ports->count);
                    273:                 }
                    274: 
                    275:                 port_names = ool_ports->address;
                    276: 
                    277:                 for(j = 0; j < ool_ports->count; j++)
                    278:                     tswap32s(&port_names[j]);
                    279: 
                    280:                 if(bswap == bswap_out)
                    281:                 {
                    282:                     tswap32s((uint32_t *)&ool_ports->address);
                    283:                     tswap32s(&ool_ports->count);
                    284:                 }
                    285: 
                    286:                 descr = (mach_msg_port_descriptor_t *)(ool_ports+1);
                    287:                 break;
                    288:             }
                    289:             default: qerror("unknow mach msg descriptor type %x\n", descr->type);
                    290:         }
                    291:     }
                    292:     if(bswap == bswap_out)
                    293:         tswap32s(&complex_msg->body.msgh_descriptor_count);
                    294: }
                    295: 
                    296: static inline void swap_mach_msg(mach_msg_header_t *hdr, int bswap)
                    297: {
                    298:     if (bswap == bswap_out && hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
                    299:         swap_mach_msg_body((struct complex_msg *)hdr, bswap);
                    300: 
                    301:     swap_mach_msg_header(hdr);
                    302: 
                    303:     if (bswap == bswap_in && hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
                    304:         swap_mach_msg_body((struct complex_msg *)hdr, bswap);
                    305: }
                    306: 
                    307: static inline uint32_t target_mach_msg_trap(
                    308:         mach_msg_header_t *hdr, uint32_t options, uint32_t send_size,
                    309:         uint32_t rcv_size, uint32_t rcv_name, uint32_t time_out, uint32_t notify)
                    310: {
                    311:     extern int mach_msg_trap(mach_msg_header_t *, mach_msg_option_t,
                    312:           mach_msg_size_t, mach_msg_size_t, mach_port_t,
                    313:           mach_msg_timeout_t, mach_port_t);
                    314:     mach_msg_audit_trailer_t *trailer;
                    315:     mach_msg_id_t msg_id;
                    316:     uint32_t ret = 0;
                    317:     int i;
                    318: 
                    319:     swap_mach_msg(hdr, bswap_in);
                    320: 
                    321:     msg_id = hdr->msgh_id;
                    322: 
                    323:     print_description_msg_header(hdr);
                    324: 
                    325:     ret = mach_msg_trap(hdr, options, send_size, rcv_size, rcv_name, time_out, notify);
                    326: 
                    327:     print_mach_msg_return(ret);
                    328: 
                    329:     if( (options & MACH_RCV_MSG) && (REQUESTED_TRAILER_SIZE(options) > 0) )
                    330:     {
                    331:         /* XXX: the kernel always return the full trailer with MACH_SEND_MSG, so we should
                    332:                 probably always bswap it  */
                    333:         /* warning: according to Mac OS X Internals (the book) msg_size might be expressed in
                    334:                     natural_t units but according to xnu/osfmk/mach/message.h: "The size of
                    335:                     the message must be specified in bytes" */
                    336:         trailer = (mach_msg_audit_trailer_t *)((uint8_t *)hdr + hdr->msgh_size);
                    337:         /* XXX: Should probably do that based on the option asked by the sender, but dealing
                    338:         with kernel answer seems more sound */
                    339:         switch(trailer->msgh_trailer_size)
                    340:         {
                    341:             case sizeof(mach_msg_audit_trailer_t):
                    342:                 for(i = 0; i < 8; i++)
                    343:                     tswap32s(&trailer->msgh_audit.val[i]);
                    344:                 /* Fall in mach_msg_security_trailer_t case */
                    345:             case sizeof(mach_msg_security_trailer_t):
                    346:                 tswap32s(&trailer->msgh_sender.val[0]);
                    347:                 tswap32s(&trailer->msgh_sender.val[1]);
                    348:                 /* Fall in mach_msg_seqno_trailer_t case */
                    349:             case sizeof(mach_msg_seqno_trailer_t):
                    350:                 tswap32s(&trailer->msgh_seqno);
                    351:                 /* Fall in mach_msg_trailer_t case */
                    352:             case sizeof(mach_msg_trailer_t):
                    353:                 tswap32s(&trailer->msgh_trailer_type);
                    354:                 tswap32s(&trailer->msgh_trailer_size);
                    355:                 break;
                    356:             case 0:
                    357:                 /* Safer not to byteswap, but probably wrong */
                    358:                 break;
                    359:             default:
                    360:                 qerror("unknow trailer type given its size %d\n", trailer->msgh_trailer_size);
                    361:                 break;
                    362:         }
                    363:     }
                    364: 
                    365:     /* Special message handling */
                    366:     switch (msg_id) {
                    367:         case 200: /* host_info */
                    368:         {
                    369:             mig_reply_error_t *err = (mig_reply_error_t *)hdr;
                    370:             struct host_basic_info *data = (void *)(err+1);
                    371: 
                    372:             DPRINTF("maxcpu = 0x%x\n",   data->max_cpus);
                    373:             DPRINTF("numcpu = 0x%x\n",   data->avail_cpus);
                    374:             DPRINTF("memsize = 0x%x\n",  data->memory_size);
                    375: 
                    376: #if defined(TARGET_I386)
                    377:             data->cpu_type = CPU_TYPE_I386;
                    378:             DPRINTF("cpu_type changed to 0x%x(i386)\n", data->cpu_type);
                    379:             data->cpu_subtype = CPU_SUBTYPE_PENT;
                    380:             DPRINTF("cpu_subtype changed to 0x%x(i386_pent)\n", data->cpu_subtype);
                    381: #elif defined(TARGET_PPC)
                    382:             data->cpu_type = CPU_TYPE_POWERPC;
                    383:             DPRINTF("cpu_type changed to 0x%x(ppc)\n", data->cpu_type);
                    384:             data->cpu_subtype = CPU_SUBTYPE_POWERPC_750;
                    385:             DPRINTF("cpu_subtype changed to 0x%x(ppc_all)\n", data->cpu_subtype);
                    386: #else
                    387: # error target not supported
                    388: #endif
                    389:             break;
                    390:         }
                    391:         case 202: /* host_page_size */
                    392:         {
                    393:             mig_reply_error_t *err = (mig_reply_error_t *)hdr;
                    394:             uint32_t *pagesize = (uint32_t *)(err+1);
                    395: 
                    396:             DPRINTF("pagesize = %d\n", *pagesize);
                    397:             break;
                    398:         }
                    399:         default: break;
                    400:     }
                    401: 
                    402:     swap_mach_msg(hdr, bswap_out);
                    403: 
                    404:     return ret;
                    405: }
                    406: 
                    407: long do_mach_syscall(void *cpu_env, int num, uint32_t arg1, uint32_t arg2, uint32_t arg3,
                    408:                 uint32_t arg4, uint32_t arg5, uint32_t arg6, uint32_t arg7,
                    409:                 uint32_t arg8)
                    410: {
                    411:     extern uint32_t mach_reply_port();
                    412: 
                    413:     long ret = 0;
                    414: 
                    415:     arg1 = tswap32(arg1);
                    416:     arg2 = tswap32(arg2);
                    417:     arg3 = tswap32(arg3);
                    418:     arg4 = tswap32(arg4);
                    419:     arg5 = tswap32(arg5);
                    420:     arg6 = tswap32(arg6);
                    421:     arg7 = tswap32(arg7);
                    422:     arg8 = tswap32(arg8);
                    423: 
                    424:     DPRINTF("mach syscall %d : " , num);
                    425: 
                    426:     switch(num) {
                    427:     /* see xnu/osfmk/mach/syscall_sw.h */
                    428:     case -26:
                    429:         DPRINTF("mach_reply_port()\n");
                    430:         ret = mach_reply_port();
                    431:         break;
                    432:     case -27:
                    433:         DPRINTF("mach_thread_self()\n");
                    434:         ret = mach_thread_self();
                    435:         break;
                    436:     case -28:
                    437:         DPRINTF("mach_task_self()\n");
                    438:         ret = mach_task_self();
                    439:         break;
                    440:     case -29:
                    441:         DPRINTF("mach_host_self()\n");
                    442:         ret = mach_host_self();
                    443:         break;
                    444:     case -31:
                    445:         DPRINTF("mach_msg_trap(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
                    446:                 arg1, arg2, arg3, arg4, arg5, arg6, arg7);
                    447: 
                    448:         ret = target_mach_msg_trap((mach_msg_header_t *)arg1, arg2, arg3, arg4, arg5, arg6, arg7);
                    449: 
                    450:         break;
                    451:     case -36:
                    452:         DPRINTF("semaphore_wait_trap(0x%x)\n", arg1);
                    453:         extern int semaphore_wait_trap(int); // XXX: is there any header for that?
                    454:         ret = semaphore_wait_trap(arg1);
                    455:         break;
                    456:     case -43:
                    457:         DPRINTF("map_fd(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
                    458:                 arg1, arg2, arg3, arg4, arg5);
                    459:         ret = map_fd(arg1, arg2, (void*)arg3, arg4, arg5);
                    460:         tswap32s((uint32_t*)arg3);
                    461:         break;
                    462:     case -89:
                    463:         DPRINTF("mach_timebase_info(0x%x)\n", arg1);
                    464:         struct mach_timebase_info info;
                    465:         ret = mach_timebase_info(&info);
                    466:         if(!is_error(ret))
                    467:         {
                    468:             struct mach_timebase_info *outInfo = (void*)arg1;
                    469:             outInfo->numer = tswap32(info.numer);
                    470:             outInfo->denom = tswap32(info.denom);
                    471:         }
                    472:         break;
                    473:     case -90:
                    474:         DPRINTF("mach_wait_until()\n");
                    475:         extern int mach_wait_until(uint64_t); // XXX: is there any header for that?
                    476:         ret = mach_wait_until(((uint64_t)arg2<<32) | (uint64_t)arg1);
                    477:         break;
                    478:     case -91:
                    479:         DPRINTF("mk_timer_create()\n");
                    480:         extern int mk_timer_create(); // XXX: is there any header for that?
                    481:         ret = mk_timer_create();
                    482:         break;
                    483:     case -92:
                    484:         DPRINTF("mk_timer_destroy()\n");
                    485:         extern int mk_timer_destroy(int); // XXX: is there any header for that?
                    486:         ret = mk_timer_destroy(arg1);
                    487:         break;
                    488:     case -93:
                    489:         DPRINTF("mk_timer_create()\n");
                    490:         extern int mk_timer_arm(int, uint64_t); // XXX: is there any header for that?
                    491:         ret = mk_timer_arm(arg1, ((uint64_t)arg3<<32) | (uint64_t)arg2);
                    492:         break;
                    493:     case -94:
                    494:         DPRINTF("mk_timer_cancel()\n");
                    495:         extern int mk_timer_cancel(int, uint64_t *); // XXX: is there any header for that?
                    496:         ret = mk_timer_cancel(arg1, (uint64_t *)arg2);
                    497:         if((!is_error(ret)) && arg2)
                    498:             tswap64s((uint64_t *)arg2);
                    499:         break;
                    500:     default:
                    501:         gemu_log("qemu: Unsupported mach syscall: %d(0x%x)\n", num, num);
                    502:         gdb_handlesig (cpu_env, SIGTRAP);
                    503:         exit(0);
                    504:         break;
                    505:     }
                    506:     return ret;
                    507: }
                    508: 
                    509: /* ------------------------------------------------------------
                    510:    thread type syscall handling
                    511: */
                    512: long do_thread_syscall(void *cpu_env, int num, uint32_t arg1, uint32_t arg2, uint32_t arg3,
                    513:                 uint32_t arg4, uint32_t arg5, uint32_t arg6, uint32_t arg7,
                    514:                 uint32_t arg8)
                    515: {
                    516:     extern uint32_t cthread_set_self(uint32_t);
                    517:     extern uint32_t processor_facilities_used();
                    518:     long ret = 0;
                    519: 
                    520:     arg1 = tswap32(arg1);
                    521:     arg2 = tswap32(arg2);
                    522:     arg3 = tswap32(arg3);
                    523:     arg4 = tswap32(arg4);
                    524:     arg5 = tswap32(arg5);
                    525:     arg6 = tswap32(arg6);
                    526:     arg7 = tswap32(arg7);
                    527:     arg8 = tswap32(arg8);
                    528: 
                    529:     DPRINTF("thread syscall %d : " , num);
                    530: 
                    531:     switch(num) {
                    532: #ifdef TARGET_I386
                    533:     case 0x3:
                    534: #endif
                    535:     case 0x7FF1: /* cthread_set_self */
                    536:         DPRINTF("cthread_set_self(0x%x)\n", (unsigned int)arg1);
                    537:         ret = cthread_set_self(arg1);
                    538: #ifdef TARGET_I386
                    539:         /* we need to update the LDT with the address of the thread */
                    540:         write_dt((void *)(((CPUX86State *) cpu_env)->ldt.base + (4 * sizeof(uint64_t))), arg1, 1,
                    541:                  DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
                    542:                  (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
                    543:         /* New i386 convention, %gs should be set to our this LDT entry */
                    544:         cpu_x86_load_seg(cpu_env, R_GS, 0x27);
                    545:         /* Old i386 convention, the kernel returns the selector for the cthread (pre-10.4.8?)*/
                    546:         ret = 0x27;
                    547: #endif
                    548:         break;
                    549:     case 0x7FF2: /* Called the super-fast pthread_self handler by the apple guys */
                    550:         DPRINTF("pthread_self()\n");
                    551:         ret = (uint32_t)pthread_self();
                    552:         break;
                    553:     case 0x7FF3:
                    554:         DPRINTF("processor_facilities_used()\n");
                    555: #ifdef __i386__
                    556:         qerror("processor_facilities_used: not implemented!\n");
                    557: #else
                    558:         ret = (uint32_t)processor_facilities_used();
                    559: #endif
                    560:         break;
                    561:     default:
                    562:         gemu_log("qemu: Unsupported thread syscall: %d(0x%x)\n", num, num);
                    563:         gdb_handlesig (cpu_env, SIGTRAP);
                    564:         exit(0);
                    565:         break;
                    566:     }
                    567:     return ret;
                    568: }
                    569: 
                    570: /* ------------------------------------------------------------
                    571:    ioctl handling
                    572: */
                    573: static inline void byteswap_termios(struct termios *t)
                    574: {
                    575:     tswap32s((uint32_t*)&t->c_iflag);
                    576:     tswap32s((uint32_t*)&t->c_oflag);
                    577:     tswap32s((uint32_t*)&t->c_cflag);
                    578:     tswap32s((uint32_t*)&t->c_lflag);
                    579:     /* 20 (char) bytes then */
                    580:     tswap32s((uint32_t*)&t->c_ispeed);
                    581:     tswap32s((uint32_t*)&t->c_ospeed);
                    582: }
                    583: 
                    584: static inline void byteswap_winsize(struct winsize *w)
                    585: {
                    586:     tswap16s(&w->ws_row);
                    587:     tswap16s(&w->ws_col);
                    588:     tswap16s(&w->ws_xpixel);
                    589:     tswap16s(&w->ws_ypixel);
                    590: }
                    591: 
                    592: #define STRUCT(name, list...) STRUCT_ ## name,
                    593: #define STRUCT_SPECIAL(name) STRUCT_ ## name,
                    594: enum {
                    595: #include "ioctls_types.h"
                    596: };
                    597: #undef STRUCT
                    598: #undef STRUCT_SPECIAL
                    599: 
                    600: #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
                    601: #define STRUCT_SPECIAL(name)
                    602: #include "ioctls_types.h"
                    603: #undef STRUCT
                    604: #undef STRUCT_SPECIAL
                    605: 
                    606: typedef struct IOCTLEntry {
                    607:     unsigned int target_cmd;
                    608:     unsigned int host_cmd;
                    609:     const char *name;
                    610:     int access;
                    611:     const argtype arg_type[5];
                    612: } IOCTLEntry;
                    613: 
                    614: #define IOC_R 0x0001
                    615: #define IOC_W 0x0002
                    616: #define IOC_RW (IOC_R | IOC_W)
                    617: 
                    618: #define MAX_STRUCT_SIZE 4096
                    619: 
                    620: IOCTLEntry ioctl_entries[] = {
                    621: #define IOCTL(cmd, access, types...) \
                    622:     { cmd, cmd, #cmd, access, { types } },
                    623: #include "ioctls.h"
                    624:     { 0, 0, },
                    625: };
                    626: 
                    627: /* ??? Implement proper locking for ioctls.  */
                    628: static long do_ioctl(long fd, long cmd, long arg)
                    629: {
                    630:     const IOCTLEntry *ie;
                    631:     const argtype *arg_type;
                    632:     int ret;
                    633:     uint8_t buf_temp[MAX_STRUCT_SIZE];
                    634:     int target_size;
                    635:     void *argptr;
                    636: 
                    637:     ie = ioctl_entries;
                    638:     for(;;) {
                    639:         if (ie->target_cmd == 0) {
                    640:             gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
                    641:             return -ENOSYS;
                    642:         }
                    643:         if (ie->target_cmd == cmd)
                    644:             break;
                    645:         ie++;
                    646:     }
                    647:     arg_type = ie->arg_type;
                    648: #if defined(DEBUG)
                    649:     gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
                    650: #endif
                    651:     switch(arg_type[0]) {
                    652:     case TYPE_NULL:
                    653:         /* no argument */
                    654:         ret = get_errno(ioctl(fd, ie->host_cmd));
                    655:         break;
                    656:     case TYPE_PTRVOID:
                    657:     case TYPE_INT:
                    658:         /* int argment */
                    659:         ret = get_errno(ioctl(fd, ie->host_cmd, arg));
                    660:         break;
                    661:     case TYPE_PTR:
                    662:         arg_type++;
                    663:         target_size = thunk_type_size(arg_type, 0);
                    664:         switch(ie->access) {
                    665:         case IOC_R:
                    666:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                    667:             if (!is_error(ret)) {
                    668:                 argptr = lock_user(arg, target_size, 0);
                    669:                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                    670:                 unlock_user(argptr, arg, target_size);
                    671:             }
                    672:             break;
                    673:         case IOC_W:
                    674:             argptr = lock_user(arg, target_size, 1);
                    675:             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                    676:             unlock_user(argptr, arg, 0);
                    677:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                    678:             break;
                    679:         default:
                    680:         case IOC_RW:
                    681:             argptr = lock_user(arg, target_size, 1);
                    682:             thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
                    683:             unlock_user(argptr, arg, 0);
                    684:             ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
                    685:             if (!is_error(ret)) {
                    686:                 argptr = lock_user(arg, target_size, 0);
                    687:                 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                    688:                 unlock_user(argptr, arg, target_size);
                    689:             }
                    690:             break;
                    691:         }
                    692:         break;
                    693:     default:
                    694:         gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
                    695:         ret = -ENOSYS;
                    696:         break;
                    697:     }
                    698:     return ret;
                    699: }
                    700: 
                    701: /* ------------------------------------------------------------
                    702:    Unix syscall handling
                    703: */
                    704: 
                    705: static inline void byteswap_attrlist(struct attrlist *a)
                    706: {
                    707:     tswap16s(&a->bitmapcount);
                    708:     tswap16s(&a->reserved);
                    709:     tswap32s(&a->commonattr);
                    710:     tswap32s(&a->volattr);
                    711:     tswap32s(&a->dirattr);
                    712:     tswap32s(&a->fileattr);
                    713:     tswap32s(&a->forkattr);
                    714: }
                    715: 
                    716: struct attrbuf_header {
                    717:     unsigned long length;
                    718: };
                    719: 
                    720: static inline void byteswap_attrbuf(struct attrbuf_header *attrbuf, struct attrlist *attrlist)
                    721: {
                    722:     DPRINTF("attrBuf.lenght %lx\n", attrbuf->length);
                    723: }
                    724: 
                    725: static inline void byteswap_statfs(struct statfs *s)
                    726: {
                    727:     tswap16s((uint16_t*)&s->f_otype);
                    728:     tswap16s((uint16_t*)&s->f_oflags);
                    729:     tswap32s((uint32_t*)&s->f_bsize);
                    730:     tswap32s((uint32_t*)&s->f_iosize);
                    731:     tswap32s((uint32_t*)&s->f_blocks);
                    732:     tswap32s((uint32_t*)&s->f_bfree);
                    733:     tswap32s((uint32_t*)&s->f_bavail);
                    734:     tswap32s((uint32_t*)&s->f_files);
                    735:     tswap32s((uint32_t*)&s->f_ffree);
                    736:     tswap32s((uint32_t*)&s->f_fsid.val[0]);
                    737:     tswap32s((uint32_t*)&s->f_fsid.val[1]);
                    738:     tswap16s((uint16_t*)&s->f_reserved1);
                    739:     tswap16s((uint16_t*)&s->f_type);
                    740:     tswap32s((uint32_t*)&s->f_flags);
                    741: }
                    742: 
                    743: static inline void byteswap_stat(struct stat *s)
                    744: {
                    745:     tswap32s((uint32_t*)&s->st_dev);
                    746:     tswap32s(&s->st_ino);
                    747:     tswap16s(&s->st_mode);
                    748:     tswap16s(&s->st_nlink);
                    749:     tswap32s(&s->st_uid);
                    750:     tswap32s(&s->st_gid);
                    751:     tswap32s((uint32_t*)&s->st_rdev);
                    752:     tswap32s((uint32_t*)&s->st_atimespec.tv_sec);
                    753:     tswap32s((uint32_t*)&s->st_atimespec.tv_nsec);
                    754:     tswap32s((uint32_t*)&s->st_mtimespec.tv_sec);
                    755:     tswap32s((uint32_t*)&s->st_mtimespec.tv_nsec);
                    756:     tswap32s((uint32_t*)&s->st_ctimespec.tv_sec);
                    757:     tswap32s((uint32_t*)&s->st_ctimespec.tv_nsec);
                    758:     tswap64s((uint64_t*)&s->st_size);
                    759:     tswap64s((uint64_t*)&s->st_blocks);
                    760:     tswap32s((uint32_t*)&s->st_blksize);
                    761:     tswap32s(&s->st_flags);
                    762:     tswap32s(&s->st_gen);
                    763: }
                    764: 
                    765: static inline void byteswap_dirents(struct dirent *d, int bytes)
                    766: {
                    767:     char *b;
                    768:     for( b = (char*)d; (int)b < (int)d+bytes; )
                    769:     {
                    770:         unsigned short s = ((struct dirent *)b)->d_reclen;
                    771:         tswap32s(&((struct dirent *)b)->d_ino);
                    772:         tswap16s(&((struct dirent *)b)->d_reclen);
                    773:         if(s<=0)
                    774:             break;
                    775:         b += s;
                    776:     }
                    777: }
                    778: 
                    779: static inline void byteswap_iovec(struct iovec *v, int n)
                    780: {
                    781:     int i;
                    782:     for(i = 0; i < n; i++)
                    783:     {
                    784:         tswap32s((uint32_t*)&v[i].iov_base);
                    785:         tswap32s((uint32_t*)&v[i].iov_len);
                    786:     }
                    787: }
                    788: 
                    789: static inline void byteswap_timeval(struct timeval *t)
                    790: {
                    791:     tswap32s((uint32_t*)&t->tv_sec);
                    792:     tswap32s((uint32_t*)&t->tv_usec);
                    793: }
                    794: 
                    795: long do_unix_syscall_indirect(void *cpu_env, int num);
                    796: long do_sync();
                    797: long do_exit(uint32_t arg1);
                    798: long do_getlogin(char *out, uint32_t size);
                    799: long do_open(char * arg1, uint32_t arg2, uint32_t arg3);
                    800: long do_getfsstat(struct statfs * arg1, uint32_t arg2, uint32_t arg3);
                    801: long do_sigprocmask(uint32_t arg1, uint32_t * arg2, uint32_t * arg3);
                    802: long do_execve(char* arg1, char ** arg2, char ** arg3);
                    803: long do_getgroups(uint32_t arg1, gid_t * arg2);
                    804: long do_gettimeofday(struct timeval * arg1, void * arg2);
                    805: long do_readv(uint32_t arg1, struct iovec * arg2, uint32_t arg3);
                    806: long do_writev(uint32_t arg1, struct iovec * arg2, uint32_t arg3);
                    807: long do_utimes(char * arg1, struct timeval * arg2);
                    808: long do_futimes(uint32_t arg1, struct timeval * arg2);
                    809: long do_statfs(char * arg1, struct statfs * arg2);
                    810: long do_fstatfs(uint32_t arg1, struct statfs * arg2);
                    811: long do_stat(char * arg1, struct stat * arg2);
                    812: long do_fstat(uint32_t arg1, struct stat * arg2);
                    813: long do_lstat(char * arg1, struct stat * arg2);
                    814: long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4);
                    815: long do_lseek(void *cpu_env, int num);
                    816: long do___sysctl(int * name, uint32_t namelen, void * oldp, size_t * oldlenp, void * newp, size_t newlen  /* ignored */);
                    817: long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32_t arg5);
                    818: long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, void * arg5, void * arg6, void* arg7, uint32_t arg8);
                    819: long do_fcntl(int fd, int cmd, int arg);
                    820: 
                    821: long no_syscall(void *cpu_env, int num);
                    822: 
                    823: long do_pread(uint32_t arg1, void * arg2, size_t arg3, off_t arg4)
                    824: {
                    825:     DPRINTF("0x%x, %p, 0x%lx, 0x%llx\n", arg1, arg2, arg3, arg4);
                    826:     long ret = pread(arg1, arg2, arg3, arg4);
                    827:     return ret;
                    828: }
                    829: 
                    830: long do_read(int d, void *buf, size_t nbytes)
                    831: {
                    832:     DPRINTF("0x%x, %p, 0x%lx\n", d, buf, nbytes);
                    833:     long ret = get_errno(read(d, buf, nbytes));
                    834:     if(!is_error(ret))
                    835:         DPRINTF("%x\n", *(uint32_t*)buf);
                    836:     return ret;
                    837: }
                    838: 
                    839: long unimpl_unix_syscall(void *cpu_env, int num);
                    840: 
                    841: typedef long (*syscall_function_t)(void *cpu_env, int num);
                    842: 
                    843: 
                    844: /* define a table that will handle the syscall number->function association */
                    845: #define VOID    void
                    846: #define INT     (uint32_t)get_int_arg(&i, cpu_env)
                    847: #define INT64   (uint64_t)get_int64_arg(&i, cpu_env)
                    848: #define UINT    (unsigned int)INT
                    849: #define PTR     (void*)INT
                    850: 
                    851: #define SIZE    INT
                    852: #define OFFSET  INT64
                    853: 
                    854: #define WRAPPER_CALL_DIRECT_0(function, args) long __qemu_##function(void *cpu_env) {  return (long)function(); }
                    855: #define WRAPPER_CALL_DIRECT_1(function, _arg1) long __qemu_##function(void *cpu_env) { int i = 0; typeof(_arg1) arg1 = _arg1;  return (long)function(arg1); }
                    856: #define WRAPPER_CALL_DIRECT_2(function, _arg1, _arg2) long __qemu_##function(void *cpu_env) { int i = 0;  typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; return (long)function(arg1, arg2); }
                    857: #define WRAPPER_CALL_DIRECT_3(function, _arg1, _arg2, _arg3) long __qemu_##function(void *cpu_env) { int i = 0;   typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; typeof(_arg3) arg3 = _arg3; return (long)function(arg1, arg2, arg3); }
                    858: #define WRAPPER_CALL_DIRECT_4(function, _arg1, _arg2, _arg3, _arg4) long __qemu_##function(void *cpu_env) { int i = 0;   typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; typeof(_arg3) arg3 = _arg3; typeof(_arg4) arg4 = _arg4; return (long)function(arg1, arg2, arg3, arg4); }
                    859: #define WRAPPER_CALL_DIRECT_5(function, _arg1, _arg2, _arg3, _arg4, _arg5) long __qemu_##function(void *cpu_env) { int i = 0;   typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; typeof(_arg3) arg3 = _arg3; typeof(_arg4) arg4 = _arg4; typeof(_arg5) arg5 = _arg5;  return (long)function(arg1, arg2, arg3, arg4, arg5); }
                    860: #define WRAPPER_CALL_DIRECT_6(function, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6) long __qemu_##function(void *cpu_env) { int i = 0;   typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; typeof(_arg3) arg3 = _arg3; typeof(_arg4) arg4 = _arg4; typeof(_arg5) arg5 = _arg5; typeof(_arg6) arg6 = _arg6;  return (long)function(arg1, arg2, arg3, arg4, arg5, arg6); }
                    861: #define WRAPPER_CALL_DIRECT_7(function, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7) long __qemu_##function(void *cpu_env) { int i = 0;   typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; typeof(_arg3) arg3 = _arg3; typeof(_arg4) arg4 = _arg4; typeof(_arg5) arg5 = _arg5; typeof(_arg6) arg6 = _arg6; typeof(_arg7) arg7 = _arg7; return (long)function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); }
                    862: #define WRAPPER_CALL_DIRECT_8(function, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8) long __qemu_##function(void *cpu_env) { int i = 0;   typeof(_arg1) arg1 = _arg1; typeof(_arg2) arg2 = _arg2; typeof(_arg3) arg3 = _arg3; typeof(_arg4) arg4 = _arg4; typeof(_arg5) arg5 = _arg5; typeof(_arg6) arg6 = _arg6; typeof(_arg7) arg7 = _arg7; typeof(_arg8) arg8 = _arg8;  return (long)function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }
                    863: #define WRAPPER_CALL_DIRECT(function, nargs, args...) WRAPPER_CALL_DIRECT_##nargs(function, args)
                    864: #define WRAPPER_CALL_NOERRNO(function, nargs, args...)  WRAPPER_CALL_DIRECT(function, nargs, args)
                    865: #define WRAPPER_CALL_INDIRECT(function, nargs, args...)
                    866: #define ENTRY(name, number, function, nargs, call_type, args...)  WRAPPER_##call_type(function, nargs, args)
                    867: 
                    868: #include "syscalls.h"
                    869: 
                    870: #undef ENTRY
                    871: #undef WRAPPER_CALL_DIRECT
                    872: #undef WRAPPER_CALL_NOERRNO
                    873: #undef WRAPPER_CALL_INDIRECT
                    874: #undef OFFSET
                    875: #undef SIZE
                    876: #undef INT
                    877: #undef PTR
                    878: #undef INT64
                    879: 
                    880: #define _ENTRY(name, number, function, nargs, call_type) [number] = {\
                    881:         name, \
                    882:         number, \
                    883:         (syscall_function_t)function, \
                    884:         nargs, \
                    885:         call_type  \
                    886:         },
                    887: 
                    888: #define ENTRY_CALL_DIRECT(name, number, function, nargs, call_type)  _ENTRY(name, number, __qemu_##function, nargs, call_type)
                    889: #define ENTRY_CALL_NOERRNO(name, number, function, nargs, call_type) ENTRY_CALL_DIRECT(name, number, function, nargs, call_type)
                    890: #define ENTRY_CALL_INDIRECT(name, number, function, nargs, call_type) _ENTRY(name, number, function, nargs, call_type)
                    891: #define ENTRY(name, number, function, nargs, call_type, args...) ENTRY_##call_type(name, number, function, nargs, call_type)
                    892: 
                    893: #define CALL_DIRECT 1
                    894: #define CALL_INDIRECT 2
                    895: #define CALL_NOERRNO  (CALL_DIRECT | 4 /* = 5 */)
                    896: 
                    897: struct unix_syscall {
                    898:     char * name;
                    899:     int number;
                    900:     syscall_function_t function;
                    901:     int nargs;
                    902:     int call_type;
                    903: } unix_syscall_table[SYS_MAXSYSCALL] = {
                    904: #include "syscalls.h"
                    905: };
                    906: 
                    907: #undef ENTRY
                    908: #undef _ENTRY
                    909: #undef ENTRY_CALL_DIRECT
                    910: #undef ENTRY_CALL_INDIRECT
                    911: #undef ENTRY_CALL_NOERRNO
                    912: 
                    913: /* Actual syscalls implementation */
                    914: 
                    915: long do_unix_syscall_indirect(void *cpu_env, int num)
                    916: {
                    917:     long ret;
                    918:     int new_num;
                    919:     int i = 0;
                    920: 
                    921:     new_num = get_int_arg(&i, cpu_env);
                    922: #ifdef TARGET_I386
                    923:     ((CPUX86State*)cpu_env)->regs[R_ESP] += 4;
                    924:     /* XXX: not necessary */
                    925:     ((CPUX86State*)cpu_env)->regs[R_EAX] = new_num;
                    926: #elif TARGET_PPC
                    927:     {
                    928:         int i;
                    929:         uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
                    930:         for(i = 3; i < 11; i++)
                    931:             *regs[i] = *regs[i+1];
                    932:         /* XXX: not necessary */
                    933:         *regs[0] = new_num;
                    934:     }
                    935: #endif
                    936:     ret = do_unix_syscall(cpu_env, new_num);
                    937: #ifdef TARGET_I386
                    938:     ((CPUX86State*)cpu_env)->regs[R_ESP] -= 4;
                    939:     /* XXX: not necessary */
                    940:     ((CPUX86State*)cpu_env)->regs[R_EAX] = num;
                    941: #elif TARGET_PPC
                    942:     {
                    943:         int i;
                    944:         /* XXX: not really needed those regs are volatile accross calls */
                    945:         uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
                    946:         for(i = 11; i > 3; i--)
                    947:             *regs[i] = *regs[i-1];
                    948:         regs[3] = new_num;
                    949:         *regs[0] = num;
                    950:     }
                    951: #endif
                    952:     return ret;
                    953: }
                    954: 
                    955: long do_exit(uint32_t arg1)
                    956: {
                    957:     exit(arg1);
                    958:     /* not reached */
                    959:     return -1;
                    960: }
                    961: 
                    962: long do_sync()
                    963: {
                    964:     sync();
                    965:     return 0;
                    966: }
                    967: 
                    968: long do_getlogin(char *out, uint32_t size)
                    969: {
                    970:     char *login = getlogin();
                    971:     if(!login)
                    972:         return -1;
                    973:     memcpy(out, login, size);
                    974:     return 0;
                    975: }
                    976: long do_open(char * arg1, uint32_t arg2, uint32_t arg3)
                    977: {
                    978:     /* XXX: don't let the %s stay in there */
                    979:     DPRINTF("open(%s, 0x%x, 0x%x)\n", arg1, arg2, arg3);
                    980:     return get_errno(open(arg1, arg2, arg3));
                    981: }
                    982: 
                    983: long do_getfsstat(struct statfs * arg1, uint32_t arg2, uint32_t arg3)
                    984: {
                    985:     long ret;
                    986:     DPRINTF("getfsstat(%p, 0x%x, 0x%x)\n", arg1, arg2, arg3);
                    987:     ret = get_errno(getfsstat(arg1, arg2, arg3));
                    988:     if((!is_error(ret)) && arg1)
                    989:         byteswap_statfs(arg1);
                    990:     return ret;
                    991: }
                    992: 
                    993: long do_sigprocmask(uint32_t arg1, uint32_t * arg2, uint32_t * arg3)
                    994: {
                    995:     long ret;
                    996:     DPRINTF("sigprocmask(%d, %p, %p)\n", arg1, arg2, arg3);
                    997:     gemu_log("XXX: sigprocmask not tested (%d, %p, %p)\n", arg1, arg2, arg3);
                    998:     if(arg2)
                    999:         tswap32s(arg2);
                   1000:     ret = get_errno(sigprocmask(arg1, (void *)arg2, (void *)arg3));
                   1001:     if((!is_error(ret)) && arg3)
                   1002:         tswap32s(arg3);
                   1003:     if(arg2)
                   1004:         tswap32s(arg2);
                   1005:     return ret;
                   1006: }
                   1007: 
                   1008: long do_execve(char* arg1, char ** arg2, char ** arg3)
                   1009: {
                   1010:     long ret;
                   1011:     char **argv = arg2;
                   1012:     char **envp = arg3;
                   1013:     int argc;
                   1014:     int envc;
                   1015: 
                   1016:     /* XXX: don't let the %s stay in here */
                   1017:     DPRINTF("execve(%s, %p, %p)\n", arg1, arg2, arg3);
                   1018: 
                   1019:     for(argc = 0; argv[argc]; argc++);
                   1020:     for(envc = 0; envp[envc]; envc++);
                   1021: 
                   1022:     argv = (char**)malloc(sizeof(char*)*argc);
                   1023:     envp = (char**)malloc(sizeof(char*)*envc);
                   1024: 
                   1025:     for(; argc >= 0; argc--)
                   1026:         argv[argc] = (char*)tswap32((uint32_t)(arg2)[argc]);
                   1027: 
                   1028:     for(; envc >= 0; envc--)
                   1029:         envp[envc] = (char*)tswap32((uint32_t)(arg3)[envc]);
                   1030: 
                   1031:     ret = get_errno(execve(arg1, argv, envp));
                   1032:     free(argv);
                   1033:     free(envp);
                   1034:     return ret;
                   1035: }
                   1036: 
                   1037: long do_getgroups(uint32_t arg1, gid_t * arg2)
                   1038: {
                   1039:     long ret;
                   1040:     int i;
                   1041:     DPRINTF("getgroups(0x%x, %p)\n", arg1, arg2);
                   1042:     ret = get_errno(getgroups(arg1, arg2));
                   1043:     if(ret > 0)
                   1044:         for(i = 0; i < arg1; i++)
                   1045:             tswap32s(&arg2[i]);
                   1046:     return ret;
                   1047: }
                   1048: 
                   1049: long do_gettimeofday(struct timeval * arg1, void * arg2)
                   1050: {
                   1051:     long ret;
                   1052:     DPRINTF("gettimeofday(%p, %p)\n",
                   1053:             arg1, arg2);
                   1054:     ret = get_errno(gettimeofday(arg1, arg2));
                   1055:     if(!is_error(ret))
                   1056:     {
                   1057:         /* timezone no longer used according to the manpage, so don't bother with it */
                   1058:         byteswap_timeval(arg1);
                   1059:     }
                   1060:     return ret;
                   1061: }
                   1062: 
                   1063: long do_readv(uint32_t arg1, struct iovec * arg2, uint32_t arg3)
                   1064: {
                   1065:     long ret;
                   1066:     DPRINTF("readv(0x%x, %p, 0x%x)\n", arg1, arg2, arg3);
                   1067:     if(arg2)
                   1068:         byteswap_iovec(arg2, arg3);
                   1069:     ret = get_errno(readv(arg1, arg2, arg3));
                   1070:     if((!is_error(ret)) && arg2)
                   1071:         byteswap_iovec(arg2, arg3);
                   1072:     return ret;
                   1073: }
                   1074: 
                   1075: long do_writev(uint32_t arg1, struct iovec * arg2, uint32_t arg3)
                   1076: {
                   1077:     long ret;
                   1078:     DPRINTF("writev(0x%x, %p, 0x%x)\n", arg1, arg2, arg3);
                   1079:     if(arg2)
                   1080:         byteswap_iovec(arg2, arg3);
                   1081:     ret = get_errno(writev(arg1, arg2, arg3));
                   1082:     if((!is_error(ret)) && arg2)
                   1083:         byteswap_iovec(arg2, arg3);
                   1084:     return ret;
                   1085: }
                   1086: 
                   1087: long do_utimes(char * arg1, struct timeval * arg2)
                   1088: {
                   1089:     DPRINTF("utimes(%p, %p)\n", arg1, arg2);
                   1090:     if(arg2)
                   1091:     {
                   1092:         byteswap_timeval(arg2);
                   1093:         byteswap_timeval(arg2+1);
                   1094:     }
                   1095:     return get_errno(utimes(arg1, arg2));
                   1096: }
                   1097: 
                   1098: long do_futimes(uint32_t arg1, struct timeval * arg2)
                   1099: {
                   1100:     DPRINTF("futimes(0x%x, %p)\n", arg1, arg2);
                   1101:     if(arg2)
                   1102:     {
                   1103:         byteswap_timeval(arg2);
                   1104:         byteswap_timeval(arg2+1);
                   1105:     }
                   1106:     return get_errno(futimes(arg1, arg2));
                   1107: }
                   1108: 
                   1109: long do_statfs(char * arg1, struct statfs * arg2)
                   1110: {
                   1111:     long ret;
                   1112:     DPRINTF("statfs(%p, %p)\n", arg1, arg2);
                   1113:     ret = get_errno(statfs(arg1, arg2));
                   1114:     if(!is_error(ret))
                   1115:         byteswap_statfs(arg2);
                   1116:     return ret;
                   1117: }
                   1118: 
                   1119: long do_fstatfs(uint32_t arg1, struct statfs* arg2)
                   1120: {
                   1121:     long ret;
                   1122:     DPRINTF("fstatfs(0x%x, %p)\n",
                   1123:             arg1, arg2);
                   1124:     ret = get_errno(fstatfs(arg1, arg2));
                   1125:     if(!is_error(ret))
                   1126:         byteswap_statfs(arg2);
                   1127: 
                   1128:     return ret;
                   1129: }
                   1130: 
                   1131: long do_stat(char * arg1, struct stat * arg2)
                   1132: {
                   1133:     long ret;
                   1134:     /* XXX: don't let the %s stay in there */
                   1135:     DPRINTF("stat(%s, %p)\n", arg1, arg2);
                   1136:     ret = get_errno(stat(arg1, arg2));
                   1137:     if(!is_error(ret))
                   1138:         byteswap_stat(arg2);
                   1139:     return ret;
                   1140: }
                   1141: 
                   1142: long do_fstat(uint32_t arg1, struct stat * arg2)
                   1143: {
                   1144:     long ret;
                   1145:     DPRINTF("fstat(0x%x, %p)\n", arg1, arg2);
                   1146:     ret = get_errno(fstat(arg1, arg2));
                   1147:     if(!is_error(ret))
                   1148:         byteswap_stat(arg2);
                   1149:     return ret;
                   1150: }
                   1151: 
                   1152: long do_lstat(char * arg1, struct stat * arg2)
                   1153: {
                   1154:     long ret;
                   1155:     /* XXX: don't let the %s stay in there */
                   1156:     DPRINTF("lstat(%s, %p)\n", (const char *)arg1, arg2);
                   1157:     ret = get_errno(lstat(arg1, arg2));
                   1158:     if(!is_error(ret))
                   1159:         byteswap_stat(arg2);
                   1160:     return ret;
                   1161: }
                   1162: 
                   1163: long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4)
                   1164: {
                   1165:     long ret;
                   1166:     DPRINTF("getdirentries(0x%x, %p, 0x%x, %p)\n", arg1, arg2, arg3, arg4);
                   1167:     if(arg4)
                   1168:         tswap32s((uint32_t *)arg4);
                   1169:     ret = get_errno(getdirentries(arg1, arg2, arg3, arg4));
                   1170:     if(arg4)
                   1171:         tswap32s((uint32_t *)arg4);
                   1172:     if(!is_error(ret))
                   1173:         byteswap_dirents(arg2, ret);
                   1174:     return ret;
                   1175: }
                   1176: 
                   1177: long do_lseek(void *cpu_env, int num)
                   1178: {
                   1179:     long ret;
                   1180:     int i = 0;
                   1181:     uint32_t arg1 = get_int_arg(&i, cpu_env);
                   1182:     uint64_t offset = get_int64_arg(&i, cpu_env);
                   1183:     uint32_t arg3 = get_int_arg(&i, cpu_env);
                   1184:     uint64_t r = lseek(arg1, offset, arg3);
                   1185: #ifdef TARGET_I386
                   1186:     /* lowest word in eax, highest in edx */
                   1187:     ret = r & 0xffffffff; /* will be set to eax after do_unix_syscall exit */
                   1188:     ((CPUX86State *)cpu_env)->regs[R_EDX] = (uint32_t)((r >> 32) & 0xffffffff) ;
                   1189: #elif defined TARGET_PPC
                   1190:     ret = r & 0xffffffff; /* will be set to r3 after do_unix_syscall exit */
                   1191:     ((CPUPPCState *)cpu_env)->gpr[4] = (uint32_t)((r >> 32) & 0xffffffff) ;
                   1192: #else
                   1193:     qerror("64 bit ret value on your arch?");
                   1194: #endif
                   1195:     return get_errno(ret);
                   1196: }
                   1197: 
                   1198: void no_swap(void * oldp, int size)
                   1199: {
                   1200: }
                   1201: 
                   1202: void sysctl_tswap32s(void * oldp, int size)
                   1203: {
                   1204:     tswap32s(oldp);
                   1205: }
                   1206: 
                   1207: void bswap_oid(uint32_t * oldp, int size)
                   1208: {
                   1209:     int count = size / sizeof(int);
                   1210:     int i = 0;
                   1211:     do { tswap32s(oldp + i); } while (++i < count);
                   1212: }
                   1213: 
                   1214: void sysctl_usrstack(uint32_t * oldp, int size)
                   1215: {
                   1216:     DPRINTF("sysctl_usrstack: 0x%x\n", *oldp);
                   1217:     tswap32s(oldp);
                   1218: }
                   1219: 
                   1220: void sysctl_ncpu(uint32_t * ncpu, int size)
                   1221: {
                   1222:     *ncpu = 0x1;
                   1223:     DPRINTF("sysctl_ncpu: 0x%x\n", *ncpu);
                   1224:     tswap32s(ncpu);
                   1225: }
                   1226: 
                   1227: void sysctl_exec(char * exec, int size)
                   1228: {
                   1229:     DPRINTF("sysctl_exec: %s\n", exec);
                   1230: }
                   1231: 
                   1232: void sysctl_translate(char * exec, int size)
                   1233: {
                   1234:     DPRINTF("sysctl_translate: %s\n", exec);
                   1235: }
                   1236: 
                   1237: struct sysctl_dir {
                   1238:     int num;
                   1239:     const char * name;
                   1240:     void (*swap_func)(void *, int);
                   1241:     struct sysctl_dir *childs;
                   1242: };
                   1243: 
                   1244: #define ENTRYD(num, name, childs) { num, name, NULL, childs }
                   1245: #define ENTRYE(num, name, func)   { num, name, (void (*)(void *, int))func, NULL  }
                   1246: struct sysctl_dir sysctls_unspec[] = {
                   1247:     ENTRYE(3,  "oip", bswap_oid),
                   1248:     { 0, NULL, NULL, NULL }
                   1249: };
                   1250: 
                   1251: struct sysctl_dir sysctls_kern[] = {
                   1252:     ENTRYE(KERN_TRANSLATE,          "translate",    sysctl_translate), /* 44 */
                   1253:     ENTRYE(KERN_EXEC,               "exec",         sysctl_exec), /* 45 */
                   1254:     ENTRYE(KERN_USRSTACK32,          "KERN_USRSTACK32", sysctl_usrstack), /* 35 */
                   1255:     ENTRYE(KERN_SHREG_PRIVATIZABLE,  "KERN_SHREG_PRIVATIZABLE", sysctl_tswap32s), /* 54 */
                   1256:     { 0, NULL, NULL, NULL }
                   1257: };
                   1258: 
                   1259: struct sysctl_dir sysctls_hw[] = {
                   1260:     ENTRYE(HW_NCPU, "ncpud", sysctl_tswap32s),
                   1261:     ENTRYE(104, "104", no_swap),
                   1262:     ENTRYE(105, "105", no_swap),
                   1263:     { 0, NULL, NULL, NULL }
                   1264: };
                   1265: 
                   1266: struct sysctl_dir sysctls[] = {
                   1267:     ENTRYD(CTL_UNSPEC, "unspec", sysctls_unspec),
                   1268:     ENTRYD(CTL_KERN, "kern", sysctls_kern),
                   1269:     ENTRYD(CTL_HW,   "hw",   sysctls_hw ),
                   1270:     { 0, NULL, NULL, NULL }
                   1271: };
                   1272: 
                   1273: #undef ENTRYE
                   1274: #undef ENTRYD
                   1275: 
                   1276: static inline struct sysctl_dir * get_sysctl_entry_for_mib(int mib, struct sysctl_dir * sysctl_elmt)
                   1277: {
                   1278:     if(!sysctl_elmt)
                   1279:         return NULL;
                   1280:     for(; sysctl_elmt->name != NULL ; sysctl_elmt++) {
                   1281:         if(sysctl_elmt->num == mib)
                   1282:             return sysctl_elmt;
                   1283:     }
                   1284:     return NULL;
                   1285: }
                   1286: 
                   1287: static inline long bswap_syctl(int * mib, int count, void *buf, int size)
                   1288: {
                   1289:     int i;
                   1290:     struct sysctl_dir * sysctl = sysctls;
                   1291:     struct sysctl_dir * ret = NULL;
                   1292: 
                   1293:     for(i = 0; i < count; i++) {
                   1294: 
                   1295:         if(!(ret = sysctl = get_sysctl_entry_for_mib(mib[i], sysctl))) {
                   1296:             gemu_log("bswap_syctl: can't find mib %d\n", mib[i]);
                   1297:             return -ENOTDIR;
                   1298:         }
                   1299:         if(!(sysctl = sysctl->childs))
                   1300:             break;
                   1301:     }
                   1302:     
                   1303:     if(ret->childs)
                   1304:         qerror("we shouldn't have a directory element\n");
                   1305: 
                   1306:     ret->swap_func(buf, size);
                   1307:     return 0;
                   1308: }
                   1309: 
                   1310: static inline void print_syctl(int * mib, int count)
                   1311: {
                   1312:     int i;
                   1313:     struct sysctl_dir * sysctl = sysctls;
                   1314:     struct sysctl_dir * ret = NULL;
                   1315: 
                   1316:     for(i = 0; i < count; i++) {
                   1317:         if(!(ret = sysctl = get_sysctl_entry_for_mib(mib[i], sysctl))){
                   1318:             gemu_log("print_syctl: can't find mib %d\n", mib[i]);
                   1319:             return;
                   1320:         }
                   1321:         DPRINTF("%s.", sysctl->name);
                   1322:         if(!(sysctl = sysctl->childs))
                   1323:             break;
                   1324:     }
                   1325:     DPRINTF("\n");
                   1326: }
                   1327: 
                   1328: long do___sysctl(int * name, uint32_t namelen, void * oldp, size_t * oldlenp, void * newp, size_t newlen  /* ignored */)
                   1329: {
                   1330:     long ret = 0;
                   1331:     int i;
                   1332:     DPRINTF("sysctl(%p, 0x%x, %p, %p, %p, 0x%lx)\n",
                   1333:             name, namelen, oldp, oldlenp, newp, newlen);
                   1334:     if(name) {
                   1335:         i = 0;
                   1336:         do { tswap32s( name + i); } while (++i < namelen);
                   1337:         print_syctl(name, namelen);
                   1338:         //bswap_syctl(name, namelen, newp, newlen);
                   1339:         tswap32s((uint32_t*)oldlenp);
                   1340:     }
                   1341:         
                   1342:     if(name) /* Sometimes sysctl is called with no arg1, ignore */
                   1343:         ret = get_errno(sysctl(name, namelen, oldp, oldlenp, newp, newlen));
                   1344: 
                   1345:     if (!is_error(ret) && bswap_syctl(name, namelen, oldp, *oldlenp) != 0) {
                   1346:         return -ENOTDIR;
                   1347:     }
                   1348:     if(name) {
                   1349:         //bswap_syctl(name, namelen, newp, newlen);
                   1350:         tswap32s((uint32_t*)oldlenp);
                   1351: 
                   1352:         i = 0;
                   1353:         do { tswap32s( name + i); } while (++i < namelen);
                   1354:     }
                   1355:     return ret;
                   1356: }
                   1357: 
                   1358: long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32_t arg5)
                   1359: {
                   1360:     struct attrlist * attrlist = (void *)arg2;
                   1361:     long ret;
                   1362: 
                   1363: #if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__)
                   1364:     gemu_log("SYS_getdirentriesattr unimplemented\n");
                   1365:     return -ENOTSUP;
                   1366: #endif
                   1367:     /* XXX: don't let the %s stay in there */
                   1368:     DPRINTF("getattrlist(%s, %p, %p, 0x%x, 0x%x)\n",
                   1369:             (char *)arg1, arg2, arg3, arg4, arg5);
                   1370: 
                   1371:     if(arg2) /* XXX: We should handle that in a copy especially
                   1372:         if the structure is not writable */
                   1373:         byteswap_attrlist(attrlist);
                   1374: 
                   1375:     ret = get_errno(getattrlist((const char* )arg1, attrlist, (void *)arg3, arg4, arg5));
                   1376: 
                   1377:     if(!is_error(ret))
                   1378:     {
                   1379:         byteswap_attrbuf((void *)arg3, attrlist);
                   1380:         byteswap_attrlist(attrlist);
                   1381:     }
                   1382:     return ret;
                   1383: }
                   1384: 
                   1385: long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, void * arg5, void * arg6, void* arg7, uint32_t arg8)
                   1386: {
                   1387:     DPRINTF("getdirentriesattr(0x%x, %p, %p, 0x%lx, %p, %p, %p, 0x%x)\n",
                   1388:             arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
                   1389: #if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__)
                   1390:     qerror("SYS_getdirentriesattr unimplemented\n");
                   1391: #endif
                   1392: 
                   1393:     return get_errno(getdirentriesattr( arg1, (struct attrlist * )arg2, (void *)arg3, arg4,
                   1394:                                        (unsigned long *)arg5, (unsigned long *)arg6,
                   1395:                                        (unsigned long *)arg7, arg8));
                   1396: }
                   1397: 
                   1398: static inline void bswap_flock(struct flock *f)
                   1399: {
                   1400:     tswap64s(&f->l_start);
                   1401:     tswap64s(&f->l_len);
                   1402:     tswap32s(&f->l_pid);
                   1403:     tswap16s(&f->l_type);
                   1404:     tswap16s(&f->l_whence);
                   1405: }
                   1406: 
                   1407: static inline void bswap_fstore(struct fstore *f)
                   1408: {
                   1409:     tswap32s(&f->fst_flags);
                   1410:     tswap32s(&f->fst_posmode);
                   1411:     tswap64s(&f->fst_offset);
                   1412:     tswap64s(&f->fst_length);
                   1413:     tswap64s(&f->fst_bytesalloc);
                   1414: }
                   1415: 
                   1416: static inline void bswap_radvisory(struct radvisory *f)
                   1417: {
                   1418:     tswap64s(&f->ra_offset);
                   1419:     tswap32s(&f->ra_count);
                   1420: }
                   1421: 
                   1422: static inline void bswap_fbootstraptransfer(struct fbootstraptransfer *f)
                   1423: {
                   1424:     tswap64s(&f->fbt_offset);
                   1425:     tswap32s((uint32_t*)&f->fbt_length);
                   1426:     tswap32s((uint32_t*)&f->fbt_buffer); /* XXX: this is a ptr */
                   1427: }
                   1428: 
                   1429: static inline void bswap_log2phys(struct log2phys *f)
                   1430: {
                   1431:     tswap32s(&f->l2p_flags);
                   1432:     tswap64s(&f->l2p_contigbytes);
                   1433:     tswap64s(&f->l2p_devoffset);
                   1434: }
                   1435: 
                   1436: static inline void bswap_fcntl_arg(int cmd, void * arg)
                   1437: {
                   1438:     switch(cmd)
                   1439:     {
                   1440:         case F_DUPFD:
                   1441:         case F_GETFD:
                   1442:         case F_SETFD:
                   1443:         case F_GETFL:
                   1444:         case F_SETFL:
                   1445:         case F_GETOWN:
                   1446:         case F_SETOWN:
                   1447:         case F_SETSIZE:
                   1448:         case F_RDAHEAD:
                   1449:         case F_FULLFSYNC:
                   1450:             break;
                   1451:         case F_GETLK:
                   1452:         case F_SETLK:
                   1453:         case F_SETLKW:
                   1454:             bswap_flock(arg);
                   1455:             break;
                   1456:         case F_PREALLOCATE:
                   1457:             bswap_fstore(arg);
                   1458:             break;
                   1459:         case F_RDADVISE:
                   1460:             bswap_radvisory(arg);
                   1461:             break;
                   1462:         case F_READBOOTSTRAP:
                   1463:         case F_WRITEBOOTSTRAP:
                   1464:             bswap_fbootstraptransfer(arg);
                   1465:             break;
                   1466:         case F_LOG2PHYS:
                   1467:             bswap_log2phys(arg);
                   1468:             break;
                   1469:         default:
                   1470:             gemu_log("unknow cmd in fcntl\n");
                   1471:     }
                   1472: }
                   1473: 
                   1474: long do_fcntl(int fd, int cmd, int arg)
                   1475: {
                   1476:     long ret;
                   1477:     bswap_fcntl_arg(cmd, (void *)arg);
                   1478:     ret = get_errno(fcntl(fd, cmd, arg));
                   1479:     if(!is_error(ret))
                   1480:         bswap_fcntl_arg(cmd, (void *)arg);
                   1481:     return ret;
                   1482: }
                   1483: 
                   1484: long no_syscall(void *cpu_env, int num)
                   1485: {
                   1486:     /* XXX: We should probably fordward it to the host kernel */
                   1487:     qerror("no unix syscall %d\n", num);
                   1488:     /* not reached */
                   1489:     return -1;
                   1490: }
                   1491: 
                   1492: long unimpl_unix_syscall(void *cpu_env, int num)
                   1493: {
                   1494:     if( (num < 0) || (num > SYS_MAXSYSCALL-1) )
                   1495:         qerror("unix syscall %d is out of unix syscall bounds (0-%d) " , num, SYS_MAXSYSCALL-1);
                   1496: 
                   1497:     gemu_log("qemu: Unsupported unix syscall %s %d\n", unix_syscall_table[num].name , num);
                   1498:     gdb_handlesig (cpu_env, SIGTRAP);
                   1499:     exit(-1);
                   1500: }
                   1501: 
                   1502: long do_unix_syscall(void *cpu_env, int num)
                   1503: {
                   1504:     long ret = 0;
                   1505: 
                   1506:     DPRINTF("unix syscall %d: " , num);
                   1507: 
                   1508:     if( (num < 0) || (num > SYS_MAXSYSCALL-1) )
                   1509:         qerror("unix syscall %d is out of unix syscall bounds (0-%d) " , num, SYS_MAXSYSCALL-1);
                   1510: 
                   1511:     DPRINTF("%s [%s]", unix_syscall_table[num].name, unix_syscall_table[num].call_type & CALL_DIRECT ? "direct" : "indirect" );
                   1512:     ret = unix_syscall_table[num].function(cpu_env, num);
                   1513: 
                   1514:     if(!(unix_syscall_table[num].call_type & CALL_NOERRNO))
                   1515:         ret = get_errno(ret);
                   1516: 
                   1517:     DPRINTF("[returned 0x%x(%d)]\n", (int)ret, (int)ret);
                   1518:     return ret;
                   1519: }
                   1520: 
                   1521: /* ------------------------------------------------------------
                   1522:    syscall_init
                   1523: */
                   1524: void syscall_init(void)
                   1525: {
                   1526:     /* Nothing yet */
                   1527: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.