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

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

unix.superglobalmegacorp.com

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