(linenum→info "unix/slp.c:2238")

qemu/0.9.1/darwin-user/syscall.c

    1: /*
    2:  *  Darwin syscalls
    3:  *
    4:  *  Copyright (c) 2003 Fabrice Bellard
    5:  *  Copyright (c) 2006 Pierre d'Herbemont
    6:  *
    7:  *  This program is free software; you can redistribute it and/or modify
    8:  *  it under the terms of the GNU General Public License as published by
    9:  *  the Free Software Foundation; either version 2 of the License, or
   10:  *  (at your option) any later version.
   11:  *
   12:  *  This program is distributed in the hope that it will be useful,
   13:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   14:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15:  *  GNU General Public License for more details.
   16:  *
   17:  *  You should have received a copy of the GNU General Public License
   18:  *  along with this program; if not, write to the Free Software
   19:  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20:  */
   21: #include <fcntl.h>
   22: #include <stdio.h>
   23: #include <stdlib.h>
   24: #include <errno.h>
   25: 
   26: #include <mach/host_info.h>
   27: #include <mach/mach.h>
   28: #include <mach/mach_time.h>
   29: #include <mach/message.h>
   30: 
   31: #include <pthread.h>
   32: #include <dirent.h>
   33: 
   34: #include <sys/stat.h>
   35: #include <sys/syscall.h>
   36: #include <sys/sysctl.h>
   37: #include <sys/types.h>
   38: #include <unistd.h>
   39: #include <sys/ioctl.h>
   40: #include <sys/mman.h>
   41: #include <sys/types.h>
   42: #include <sys/dirent.h>
   43: #include <sys/uio.h>
   44: #include <sys/termios.h>
   45: #include <sys/ptrace.h>
   46: #include <net/if.h>
   47: 
   48: #include <sys/param.h>
   49: #include <sys/mount.h>
   50: 
   51: #include <sys/attr.h>
   52: 
   53: #include <mach/ndr.h>
   54: #include <mach/mig_errors.h>
   55: 
   56: #include <sys/xattr.h>
   57: 
   58: #include "qemu.h"
   59: 
   60: //#define DEBUG_SYSCALL
   61: 
   62: #ifdef DEBUG_SYSCALL
   63: # define DEBUG_FORCE_ENABLE_LOCAL() int __DEBUG_qemu_user_force_enable = 1
   64: # define DEBUG_BEGIN_ENABLE  __DEBUG_qemu_user_force_enable = 1;
   65: # define DEBUG_END_ENABLE  __DEBUG_qemu_user_force_enable = 0;
   66: 
   67: # define DEBUG_DISABLE_ALL() static int __DEBUG_qemu_user_force_enable = 0
   68: # define DEBUG_ENABLE_ALL()  static int __DEBUG_qemu_user_force_enable = 1
   69:     DEBUG_ENABLE_ALL();
   70: 
   71: # define DPRINTF(...) do { if(loglevel) fprintf(logfile, __VA_ARGS__); \
   72:                            if(__DEBUG_qemu_user_force_enable) fprintf(stderr, __VA_ARGS__); \
   73:                          } while(0)
   74: #else
   75: # define DEBUG_FORCE_ENABLE_LOCAL()
   76: # define DEBUG_BEGIN_ENABLE
   77: # define DEBUG_END_ENABLE
   78: 
   79: # define DPRINTF(...) do { if(loglevel) fprintf(logfile, __VA_ARGS__); } while(0)
   80: #endif
   81: 
   82: enum {
   83:     bswap_out = 0,
   84:     bswap_in = 1
   85: };
   86: 
   87: extern const char *interp_prefix;
   88: 
   89: static inline long get_errno(long ret)
   90: {
   91:     if (ret == -1)
   92:         return -errno;
   93:     else
   94:         return ret;
   95: }
   96: 
   97: static inline int is_error(long ret)
   98: {
   99:     return (unsigned long)ret >= (unsigned long)(-4096);
  100: }
  101: 
  102: /* ------------------------------------------------------------
  103:    Mach syscall handling
  104: */
  105: 
  106: void static inline print_description_msg_header(mach_msg_header_t *hdr)
  107: {
  108:     char *name = NULL;
  109:     int i;
  110:     struct { int number; char *name; } msg_name[] =
  111:     {
  112:         /* see http://fxr.watson.org/fxr/source/compat/mach/mach_namemap.c?v=NETBSD */
  113:         { 200,      "host_info" },
  114:         { 202,      "host_page_size" },
  115:         { 206,      "host_get_clock_service" },
  116:         { 206,      "host_get_clock_service" },
  117:         { 206,      "host_get_clock_service" },
  118:         { 306,      "host_get_clock_service" },
  119:         { 3204,     "mach_port_allocate" },
  120:         { 3206,     "mach_port_deallocate" },
  121:         { 3404,     "mach_ports_lookup" },
  122:         { 3409,     "mach_task_get_special_port" },
  123:         { 3414,     "mach_task_get_exception_ports" },
  124:         { 3418,     "mach_semaphore_create" },
  125:         { 3504,     "mach_semaphore_create" },
  126:         { 3509,     "mach_semaphore_create" },
  127:         { 3518,     "semaphore_create" },
  128:         { 3616,     "thread_policy" },
  129:         { 3801,     "vm_allocate" },
  130:         { 3802,     "vm_deallocate" },
  131:         { 3802,     "vm_deallocate" },
  132:         { 3803,     "vm_protect" },
  133:         { 3812,     "vm_map" },
  134:         { 4241776,  "lu_message_send_id" },  /* lookupd */
  135:         { 4241876,  "lu_message_reply_id" }, /* lookupd */
  136:     };
  137: 
  138:     for(i = 0; i < sizeof(msg_name)/sizeof(msg_name[0]); i++) {
  139:         if(msg_name[i].number == hdr->msgh_id)
  140:         {
  141:             name = msg_name[i].name;
  142:             break;
  143:         }
  144:     }
  145:     if(!name)
  146:         DPRINTF("unknown mach msg %d 0x%x\n", hdr->msgh_id, hdr->msgh_id);
  147:     else
  148:         DPRINTF("%s\n", name);
  149: #if 0
  150:     DPRINTF("Bits: %8x\n", hdr->msgh_bits);
  151:     DPRINTF("Size: %8x\n", hdr->msgh_size);
  152:     DPRINTF("Rmte: %8x\n", hdr->msgh_remote_port);
  153:     DPRINTF("Locl: %8x\n", hdr->msgh_local_port);
  154:     DPRINTF("Rsrv: %8x\n", hdr->msgh_reserved);
  155: 
  156:     DPRINTF("Id  : %8x\n", hdr->msgh_id);
  157: 
  158:     NDR_record_t *ndr = (NDR_record_t *)(hdr + 1);
  159:     DPRINTF("hdr = %p, sizeof(hdr) = %x, NDR = %p\n", hdr, (unsigned int)sizeof(mach_msg_header_t), ndr);
  160:     DPRINTF("%d %d %d %d %d %d %d %d\n",
  161:            ndr->mig_vers, ndr->if_vers, ndr->reserved1, ndr->mig_encoding,
  162:            ndr->int_rep, ndr->char_rep, ndr->float_rep, ndr->reserved2);
  163: #endif
  164: }
  165: 
  166: static inline void print_mach_msg_return(mach_msg_return_t ret)
  167: {
  168:     int i, found = 0;
  169: #define MACH_MSG_RET(msg) { msg, #msg }
  170:     struct { int code; char *name; } msg_name[] =
  171:     {
  172:         /* ref: http://darwinsource.opendarwin.org/10.4.2/xnu-792.2.4/osfmk/man/mach_msg.html */
  173:         /* send message */
  174:         MACH_MSG_RET(MACH_SEND_MSG_TOO_SMALL),
  175:         MACH_MSG_RET(MACH_SEND_NO_BUFFER),
  176:         MACH_MSG_RET(MACH_SEND_INVALID_DATA),
  177:         MACH_MSG_RET(MACH_SEND_INVALID_HEADER),
  178:         MACH_MSG_RET(MACH_SEND_INVALID_DEST),
  179:         MACH_MSG_RET(MACH_SEND_INVALID_NOTIFY),
  180:         MACH_MSG_RET(MACH_SEND_INVALID_REPLY),
  181:         MACH_MSG_RET(MACH_SEND_INVALID_TRAILER),
  182:         MACH_MSG_RET(MACH_SEND_INVALID_MEMORY),
  183:         MACH_MSG_RET(MACH_SEND_INVALID_RIGHT),
  184:         MACH_MSG_RET(MACH_SEND_INVALID_TYPE),
  185:         MACH_MSG_RET(MACH_SEND_INTERRUPTED),
  186:         MACH_MSG_RET(MACH_SEND_TIMED_OUT),
  187: 
  188:         MACH_MSG_RET(MACH_RCV_BODY_ERROR),
  189:         MACH_MSG_RET(MACH_RCV_HEADER_ERROR),
  190: 
  191:         MACH_MSG_RET(MACH_RCV_IN_SET),
  192:         MACH_MSG_RET(MACH_RCV_INTERRUPTED),
  193: 
  194:         MACH_MSG_RET(MACH_RCV_INVALID_DATA),
  195:         MACH_MSG_RET(MACH_RCV_INVALID_NAME),
  196:         MACH_MSG_RET(MACH_RCV_INVALID_NOTIFY),
  197:         MACH_MSG_RET(MACH_RCV_INVALID_TRAILER),
  198:         MACH_MSG_RET(MACH_RCV_INVALID_TYPE),
  199: 
  200:         MACH_MSG_RET(MACH_RCV_PORT_CHANGED),
  201:         MACH_MSG_RET(MACH_RCV_PORT_DIED),
  202: 
  203:         MACH_MSG_RET(MACH_RCV_SCATTER_SMALL),
  204:         MACH_MSG_RET(MACH_RCV_TIMED_OUT),
  205:         MACH_MSG_RET(MACH_RCV_TOO_LARGE)
  206:     };
  207: #undef MACH_MSG_RET
  208: 
  209:     if( ret == MACH_MSG_SUCCESS)
  210:         DPRINTF("MACH_MSG_SUCCESS\n");
  211:     else
  212:     {
  213:         for( i = 0; i < sizeof(msg_name)/sizeof(msg_name[0]); i++) {
  214:             if(msg_name[i].code == ret) {
  215:                 DPRINTF("%s\n", msg_name[i].name);
  216:                 found = 1;
  217:                 break;
  218:             }
  219:         }
  220:         if(!found)
  221:             qerror("unknow mach message ret code %d\n", ret);
  222:     }
  223: }
  224: 
  225: static inline void swap_mach_msg_header(mach_msg_header_t *hdr)
  226: {
  227:     hdr->msgh_bits = tswap32(hdr->msgh_bits);
  228:     hdr->msgh_size = tswap32(hdr->msgh_size);
  229:     hdr->msgh_remote_port = tswap32(hdr->msgh_remote_port);
  230:     hdr->msgh_local_port = tswap32(hdr->msgh_local_port);
  231:     hdr->msgh_reserved = tswap32(hdr->msgh_reserved);
  232:     hdr->msgh_id = tswap32(hdr->msgh_id);
  233: }
  234: 
  235: struct complex_msg {
  236:             mach_msg_header_t hdr;
  237:             mach_msg_body_t body;
  238: };
  239: 
  240: static inline void swap_mach_msg_body(struct complex_msg *complex_msg, int bswap)
  241: {
  242:     mach_msg_port_descriptor_t *descr = (mach_msg_port_descriptor_t *)(complex_msg+1);
  243:     int i,j;
  244: 
  245:     if(bswap == bswap_in)
  246:         tswap32s(&complex_msg->body.msgh_descriptor_count);
  247: 
  248:     DPRINTF("body.msgh_descriptor_count %d\n", complex_msg->body.msgh_descriptor_count);
  249: 
  250:     for(i = 0; i < complex_msg->body.msgh_descriptor_count; i++) {
  251:         switch(descr->type)
  252:         {
  253:             case MACH_MSG_PORT_DESCRIPTOR:
  254:                 tswap32s(&descr->name);
  255:                 descr++;
  256:                 break;
  257:             case MACH_MSG_OOL_DESCRIPTOR:
  258:             {
  259:                 mach_msg_ool_descriptor_t *ool = (void *)descr;
  260:                 tswap32s((uint32_t *)&ool->address);
  261:                 tswap32s(&ool->size);
  262: 
  263:                 descr = (mach_msg_port_descriptor_t *)(ool+1);
  264:                 break;
  265:             }
  266:             case MACH_MSG_OOL_PORTS_DESCRIPTOR:
  267:             {
  268:                 mach_msg_ool_ports_descriptor_t *ool_ports = (void *)descr;
  269:                 mach_port_name_t * port_names;
  270: 
  271:                 if(bswap == bswap_in)
  272:                 {
  273:                     tswap32s((uint32_t *)&ool_ports->address);
  274:                     tswap32s(&ool_ports->count);
  275:                 }
  276: 
  277:                 port_names = ool_ports->address;
  278: 
  279:                 for(j = 0; j < ool_ports->count; j++)
  280:                     tswap32s(&port_names[j]);
  281: 
  282:                 if(bswap == bswap_out)
  283:                 {
  284:                     tswap32s((uint32_t *)&ool_ports->address);
  285:                     tswap32s(&ool_ports->count);
  286:                 }
  287: 
  288:                 descr = (mach_msg_port_descriptor_t *)(ool_ports+1);
  289:                 break;
  290:             }
  291:             default: qerror("unknow mach msg descriptor type %x\n", descr->type);
  292:         }
  293:     }
  294:     if(bswap == bswap_out)
  295:         tswap32s(&complex_msg->body.msgh_descriptor_count);
  296: }
  297: 
  298: static inline void swap_mach_msg(mach_msg_header_t *hdr, int bswap)
  299: {
  300:     if (bswap == bswap_out && hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
  301:         swap_mach_msg_body((struct complex_msg *)hdr, bswap);
  302: 
  303:     swap_mach_msg_header(hdr);
  304: 
  305:     if (bswap == bswap_in && hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
  306:         swap_mach_msg_body((struct complex_msg *)hdr, bswap);
  307: }
  308: 
  309: static inline uint32_t target_mach_msg_trap(
  310:         mach_msg_header_t *hdr, uint32_t options, uint32_t send_size,
  311:         uint32_t rcv_size, uint32_t rcv_name, uint32_t time_out, uint32_t notify)
  312: {
  313:     extern int mach_msg_trap(mach_msg_header_t *, mach_msg_option_t,
  314:           mach_msg_size_t, mach_msg_size_t, mach_port_t,
  315:           mach_msg_timeout_t, mach_port_t);
  316:     mach_msg_audit_trailer_t *trailer;
  317:     mach_msg_id_t msg_id;
  318:     uint32_t ret = 0;
  319:     int i;
  320: 
  321:     swap_mach_msg(hdr, bswap_in);
  322: 
  323:     msg_id = hdr->msgh_id;
  324: 
  325:     print_description_msg_header(hdr);
  326: 
  327:     ret = mach_msg_trap(hdr, options, send_size, rcv_size, rcv_name, time_out, notify);
  328: 
  329:     print_mach_msg_return(ret);
  330: 
  331:     if( (options & MACH_RCV_MSG) && (REQUESTED_TRAILER_SIZE(options) > 0) )
  332:     {
  333:         /* XXX: the kernel always return the full trailer with MACH_SEND_MSG, so we should
  334:                 probably always bswap it  */
  335:         /* warning: according to Mac OS X Internals (the book) msg_size might be expressed in
  336:                     natural_t units but according to xnu/osfmk/mach/message.h: "The size of
  337:                     the message must be specified in bytes" */
  338:         trailer = (mach_msg_audit_trailer_t *)((uint8_t *)hdr + hdr->msgh_size);
  339:         /* XXX: Should probably do that based on the option asked by the sender, but dealing
  340:         with kernel answer seems more sound */
  341:         switch(trailer->msgh_trailer_size)
  342:         {
  343:             case sizeof(mach_msg_audit_trailer_t):
  344:                 for(i = 0; i < 8; i++)
  345:                     tswap32s(&trailer->msgh_audit.val[i]);
  346:                 /* Fall in mach_msg_security_trailer_t case */
  347:             case sizeof(mach_msg_security_trailer_t):
  348:                 tswap32s(&trailer->msgh_sender.val[0]);
  349:                 tswap32s(&trailer->msgh_sender.val[1]);
  350:                 /* Fall in mach_msg_seqno_trailer_t case */
  351:             case sizeof(mach_msg_seqno_trailer_t):
  352:                 tswap32s(&trailer->msgh_seqno);
  353:                 /* Fall in mach_msg_trailer_t case */
  354:             case sizeof(mach_msg_trailer_t):
  355:                 tswap32s(&trailer->msgh_trailer_type);
  356:                 tswap32s(&trailer->msgh_trailer_size);
  357:                 break;
  358:             case 0:
  359:                 /* Safer not to byteswap, but probably wrong */
  360:                 break;
  361:             default:
  362:                 qerror("unknow trailer type given its size %d\n", trailer->msgh_trailer_size);
  363:                 break;
  364:         }
  365:     }
  366: 
  367:     /* Special message handling */
  368:     switch (msg_id) {
  369:         case 200: /* host_info */
  370:         {
  371:             mig_reply_error_t *err = (mig_reply_error_t *)hdr;
  372:             struct {
  373:                 uint32_t unknow1;
  374:                 uint32_t max_cpus;
  375:                 uint32_t avail_cpus;
  376:                 uint32_t memory_size;
  377:                 uint32_t cpu_type;
  378:                 uint32_t cpu_subtype;
  379:             } *data = (void *)(err+1);
  380: 
  381:             DPRINTF("maxcpu = 0x%x\n",   data->max_cpus);
  382:             DPRINTF("numcpu = 0x%x\n",   data->avail_cpus);
  383:             DPRINTF("memsize = 0x%x\n",  data->memory_size);
  384: 
  385: #if defined(TARGET_I386)
  386:             data->cpu_type = CPU_TYPE_I386;
  387:             DPRINTF("cpu_type changed to 0x%x(i386)\n", data->cpu_type);
  388:             data->cpu_subtype = CPU_SUBTYPE_PENT;
  389:             DPRINTF("cpu_subtype changed to 0x%x(i386_pent)\n", data->cpu_subtype);
  390: #elif defined(TARGET_PPC)
  391:             data->cpu_type = CPU_TYPE_POWERPC;
  392:             DPRINTF("cpu_type changed to 0x%x(ppc)\n", data->cpu_type);
  393:             data->cpu_subtype = CPU_SUBTYPE_POWERPC_750;
  394:             DPRINTF("cpu_subtype changed to 0x%x(ppc_all)\n", data->cpu_subtype);
  395: #else
  396: # error target not supported
  397: #endif
  398:             break;
  399:         }
  400:         case 202: /* host_page_size */
  401:         {
  402:             mig_reply_error_t *err = (mig_reply_error_t *)hdr;
  403:             uint32_t *pagesize = (uint32_t *)(err+1);
  404: 
  405:             DPRINTF("pagesize = %d\n", *pagesize);
  406:             break;
  407:         }
  408:         default: break;
  409:     }
  410: 
  411:     swap_mach_msg(hdr, bswap_out);
  412: 
  413:     return ret;
  414: }
  415: 
  416: long do_mach_syscall(void *cpu_env, int num, uint32_t arg1, uint32_t arg2, uint32_t arg3,
  417:                 uint32_t arg4, uint32_t arg5, uint32_t arg6, uint32_t arg7,
  418:                 uint32_t arg8)
  419: {
  420:     extern uint32_t mach_reply_port();
  421: 
  422:     long ret = 0;
  423: 
  424:     arg1 = tswap32(arg1);
  425:     arg2 = tswap32(arg2);
  426:     arg3 = tswap32(arg3);
  427:     arg4 = tswap32(arg4);
  428:     arg5 = tswap32(arg5);
  429:     arg6 = tswap32(arg6);
  430:     arg7 = tswap32(arg7);
  431:     arg8 = tswap32(arg8);
  432: 
  433:     DPRINTF("mach syscall %d : " , num);
  434: 
  435:     switch(num) {
  436:     /* see xnu/osfmk/mach/syscall_sw.h */
  437:     case -26:
  438:         DPRINTF("mach_reply_port()\n");
  439:         ret = mach_reply_port();
  440:         break;
  441:     case -27:
  442:         DPRINTF("mach_thread_self()\n");
  443:         ret = mach_thread_self();
  444:         break;
  445:     case -28:
  446:         DPRINTF("mach_task_self()\n");
  447:         ret = mach_task_self();
  448:         break;
  449:     case -29:
  450:         DPRINTF("mach_host_self()\n");
  451:         ret = mach_host_self();
  452:         break;
  453:     case -31:
  454:         DPRINTF("mach_msg_trap(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
  455:                 arg1, arg2, arg3, arg4, arg5, arg6, arg7);
  456:         ret = target_mach_msg_trap((mach_msg_header_t *)arg1, arg2, arg3, arg4, arg5, arg6, arg7);
  457:         break;
  458: /* may need more translation if target arch is different from host */
  459: #if (defined(TARGET_I386) && defined(__i386__)) || (defined(TARGET_PPC) && defined(__ppc__))
  460:     case -33:
  461:         DPRINTF("semaphore_signal_trap(0x%x)\n", arg1);
  462:         ret = semaphore_signal_trap(arg1);
  463:         break;
  464:     case -34:
  465:         DPRINTF("semaphore_signal_all_trap(0x%x)\n", arg1);
  466:         ret = semaphore_signal_all_trap(arg1);
  467:         break;
  468:     case -35:
  469:         DPRINTF("semaphore_signal_thread_trap(0x%x)\n", arg1, arg2);
  470:         ret = semaphore_signal_thread_trap(arg1,arg2);
  471:         break;
  472: #endif
  473:     case -36:
  474:         DPRINTF("semaphore_wait_trap(0x%x)\n", arg1);
  475:         extern int semaphore_wait_trap(int); // XXX: is there any header for that?
  476:         ret = semaphore_wait_trap(arg1);
  477:         break;
  478: /* may need more translation if target arch is different from host */
  479: #if (defined(TARGET_I386) && defined(__i386__)) || (defined(TARGET_PPC) && defined(__ppc__))
  480:     case -37:
  481:         DPRINTF("semaphore_wait_signal_trap(0x%x, 0x%x)\n", arg1, arg2);
  482:         ret = semaphore_wait_signal_trap(arg1,arg2);
  483:         break;
  484: #endif
  485:     case -43:
  486:         DPRINTF("map_fd(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
  487:                 arg1, arg2, arg3, arg4, arg5);
  488:         ret = map_fd(arg1, arg2, (void*)arg3, arg4, arg5);
  489:         tswap32s((uint32_t*)arg3);
  490:         break;
  491: /* may need more translation if target arch is different from host */
  492: #if (defined(TARGET_I386) && defined(__i386__)) || (defined(TARGET_PPC) && defined(__ppc__))
  493:     case -61:
  494:         DPRINTF("syscall_thread_switch(0x%x, 0x%x, 0x%x)\n",
  495:                 arg1, arg2, arg3);
  496:         ret = syscall_thread_switch(arg1, arg2, arg3);  // just a hint to the scheduler; can drop?
  497:         break;
  498: #endif
  499:     case -89:
  500:         DPRINTF("mach_timebase_info(0x%x)\n", arg1);
  501:         struct mach_timebase_info info;
  502:         ret = mach_timebase_info(&info);
  503:         if(!is_error(ret))
  504:         {
  505:             struct mach_timebase_info *outInfo = (void*)arg1;
  506:             outInfo->numer = tswap32(info.numer);
  507:             outInfo->denom = tswap32(info.denom);
  508:         }
  509:         break;
  510:     case -90:
  511:         DPRINTF("mach_wait_until()\n");
  512:         extern int mach_wait_until(uint64_t); // XXX: is there any header for that?
  513:         ret = mach_wait_until(((uint64_t)arg2<<32) | (uint64_t)arg1);
  514:         break;
  515:     case -91:
  516:         DPRINTF("mk_timer_create()\n");
  517:         extern int mk_timer_create(); // XXX: is there any header for that?
  518:         ret = mk_timer_create();
  519:         break;
  520:     case -92:
  521:         DPRINTF("mk_timer_destroy()\n");
  522:         extern int mk_timer_destroy(int); // XXX: is there any header for that?
  523:         ret = mk_timer_destroy(arg1);
  524:         break;
  525:     case -93:
  526:         DPRINTF("mk_timer_create()\n");
  527:         extern int mk_timer_arm(int, uint64_t); // XXX: is there any header for that?
  528: