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

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

unix.superglobalmegacorp.com

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