コード例 #1
0
ファイル: communication.c プロジェクト: berkus/flick
  /* mig_put_reply_port(_buf_start->Head.msgh_local_port); */
	
#if 0
  if (_buf_start->RetCode != KERN_SUCCESS)
    fprintf(stderr,"Return error code: %x\n", _buf_start->RetCode);
#endif
  
  return mr;
}


#if 0 /* the send is handled by a direct call to mach_msg now */
mach_msg_return_t flick_mach3mig_send(void *buf_current,
				      mach_msg_option_t msg_options,
				      mach_msg_timeout_t timeout)
{
  register mig_reply_header_t *_buf_start = _global_buf_start;
  register void *_buf_current = buf_current;
  mach_msg_return_t mr;

  _buf_start->Head.msgh_local_port = MACH_PORT_NULL;

#if 0
  printf("Send:\n");
  print_message(_buf_start, _buf_start->Head.msgh_size);
#endif
  mr = mach_msg(&_buf_start->Head, MACH_SEND_MSG|msg_options,
		_buf_start->Head.msgh_size, 0,
		MACH_PORT_NULL, timeout, MACH_PORT_NULL);
  
  if (mr != MACH_MSG_SUCCESS)
    {
	  
      while (mr == MACH_SEND_INTERRUPTED)
	{
	  /* Retry both the send and the receive.  */
	  mr = mach_msg_trap(&_buf_start->Head,
			     MACH_SEND_MSG,
			     _buf_start->Head.msgh_size, 0,
			     MACH_PORT_NULL, 0, 0);
	}
	  
      if (mr != MACH_MSG_SUCCESS)
	{
#if 0
	if ((mr == MACH_SEND_INVALID_REPLY) ||
	      (mr == MACH_SEND_INVALID_MEMORY) ||
	      (mr == MACH_SEND_INVALID_RIGHT) ||
	      (mr == MACH_SEND_INVALID_TYPE) ||
	      (mr == MACH_SEND_MSG_TOO_SMALL) ||
	      (mr == MACH_RCV_INVALID_NAME))
	    mig_dealloc_reply_port(_buf_start->Head.msgh_local_port);
	  else
	    mig_put_reply_port(_buf_start->Head.msgh_local_port);
#endif
	return mr;
	}
    }

#if 0
  if (_buf_start->RetCode != KERN_SUCCESS)
    fprintf(stderr,"Return error code: %x\n", _buf_start->RetCode);
#endif
  
  return mr;
}
コード例 #2
0
ファイル: thread_darwin.c プロジェクト: icattlecoder/go
static int32
mach_msg(MachHeader *h,
	int32 op,
	uint32 send_size,
	uint32 rcv_size,
	uint32 rcv_name,
	uint32 timeout,
	uint32 notify)
{
	// TODO: Loop on interrupt.
	return runtime·mach_msg_trap(h, op, send_size, rcv_size, rcv_name, timeout, notify);
}
コード例 #3
0
ファイル: communication.c プロジェクト: berkus/flick
mach_msg_return_t flick_mach3mig_rpc(mach_msg_option_t msg_options,
				     mach_msg_timeout_t timeout)
{
  register mig_reply_header_t *_buf_start = _global_buf_start;
  mach_msg_return_t mr;

  int buf_size = ((int)_buf_end - (int)_buf_start);

  /*
   * Consider the following cases:
   *	1) Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED
   *	plus special bits).
   *	2) Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options.
   *	3) RPC calls with interruptions in one/both halves.
   *	4) Exception reply messages that are bigger
   *	   than the expected non-exception reply message.
   *
   * We refrain from passing the option bits that we implement
   * to the kernel.  This prevents their presence from inhibiting
   * the kernel's fast paths (when it checks the option value).
   */
  
  
#if 0
  printf("RPC-SND:\n");
  print_message(_buf_start, _buf_start->Head.msgh_size);
#endif
  
  mr = mach_msg(&_buf_start->Head,
		MACH_SEND_MSG | MACH_RCV_MSG | MACH_RCV_LARGE | msg_options,
		_buf_start->Head.msgh_size, buf_size,
		_buf_start->Head.msgh_local_port, timeout, MACH_PORT_NULL);

  if (mr != MACH_MSG_SUCCESS)
    {
      while (mr == MACH_SEND_INTERRUPTED)
	{
	  /* Retry both the send and the receive.  */
	  mr = mach_msg_trap(&_buf_start->Head,
			     (MACH_SEND_MSG | MACH_RCV_MSG |
			      MACH_RCV_LARGE | msg_options),
			     _buf_start->Head.msgh_size, buf_size,
			     _buf_start->Head.msgh_local_port,
			     timeout, MACH_PORT_NULL);
	}
	  
      while ((mr == MACH_RCV_INTERRUPTED) || (mr == MACH_RCV_TOO_LARGE))
	{
	  if (mr == MACH_RCV_TOO_LARGE)
	    {
	      /* Oops, message too large - grow the buffer.  */
	      buf_size = _buf_start->Head.msgh_size;
	      if (!(_buf_start = (mig_reply_header_t *)
		    nonposix_realloc(_buf_start, buf_size)))
		{
		  mig_dealloc_reply_port(/*_buf_start->Head.msgh_local_port*/);
		  return FLICK_NO_MEMORY;
		}
#if 0
	      __buffer = _buf_start;
	      __buflen = buf_size;
#endif
	    } 
	      
	      
	  /* Retry the receive only
	     (the request message has already been sent successfully).  */
	  mr = mach_msg_trap(&_buf_start->Head,
			     MACH_RCV_MSG|MACH_RCV_LARGE|msg_options,
			     0, buf_size, _buf_start->Head.msgh_local_port,
			     timeout, MACH_PORT_NULL);
	}
	  
      if (mr != MACH_MSG_SUCCESS)
	{
#if 0
	  if ((mr == MACH_SEND_INVALID_REPLY) ||
	      (mr == MACH_SEND_INVALID_MEMORY) ||
	      (mr == MACH_SEND_INVALID_RIGHT) ||
	      (mr == MACH_SEND_INVALID_TYPE) ||
	      (mr == MACH_SEND_MSG_TOO_SMALL) ||
	      (mr == MACH_RCV_INVALID_NAME))
	    mig_dealloc_reply_port(_buf_start->Head.msgh_local_port);
	  else
	    mig_put_reply_port(_buf_start->Head.msgh_local_port);
#endif
	  return mr;
	}
    }
	
#if 0
  printf("RPC-RCV: (%d, 0x%08x)\n", mr, mr);
  print_message(_buf_start, _buf_start->Head.msgh_size);
  scanf("%d",&mr);
#endif

  /* Stash the reply port again for future use.  */
  /* mig_put_reply_port(_buf_start->Head.msgh_local_port); */
	
#if 0
  if (_buf_start->RetCode != KERN_SUCCESS)
    fprintf(stderr,"Return error code: %x\n", _buf_start->RetCode);
#endif
  
  return mr;
}
コード例 #4
0
ファイル: syscall.c プロジェクト: hackndev/qemu
static inline uint32_t target_mach_msg_trap(
        mach_msg_header_t *hdr, uint32_t options, uint32_t send_size,
        uint32_t rcv_size, uint32_t rcv_name, uint32_t time_out, uint32_t notify)
{
    extern int mach_msg_trap(mach_msg_header_t *, mach_msg_option_t,
          mach_msg_size_t, mach_msg_size_t, mach_port_t,
          mach_msg_timeout_t, mach_port_t);
    mach_msg_audit_trailer_t *trailer;
    mach_msg_id_t msg_id;
    uint32_t ret = 0;
    int i;

    swap_mach_msg(hdr, bswap_in);

    msg_id = hdr->msgh_id;

    print_description_msg_header(hdr);

    ret = mach_msg_trap(hdr, options, send_size, rcv_size, rcv_name, time_out, notify);

    print_mach_msg_return(ret);

    if( (options & MACH_RCV_MSG) && (REQUESTED_TRAILER_SIZE(options) > 0) )
    {
        /* XXX: the kernel always return the full trailer with MACH_SEND_MSG, so we should
                probably always bswap it  */
        /* warning: according to Mac OS X Internals (the book) msg_size might be expressed in
                    natural_t units but according to xnu/osfmk/mach/message.h: "The size of
                    the message must be specified in bytes" */
        trailer = (mach_msg_audit_trailer_t *)((uint8_t *)hdr + hdr->msgh_size);
        /* XXX: Should probably do that based on the option asked by the sender, but dealing
        with kernel answer seems more sound */
        switch(trailer->msgh_trailer_size)
        {
            case sizeof(mach_msg_audit_trailer_t):
                for(i = 0; i < 8; i++)
                    tswap32s(&trailer->msgh_audit.val[i]);
                /* Fall in mach_msg_security_trailer_t case */
            case sizeof(mach_msg_security_trailer_t):
                tswap32s(&trailer->msgh_sender.val[0]);
                tswap32s(&trailer->msgh_sender.val[1]);
                /* Fall in mach_msg_seqno_trailer_t case */
            case sizeof(mach_msg_seqno_trailer_t):
                tswap32s(&trailer->msgh_seqno);
                /* Fall in mach_msg_trailer_t case */
            case sizeof(mach_msg_trailer_t):
                tswap32s(&trailer->msgh_trailer_type);
                tswap32s(&trailer->msgh_trailer_size);
                break;
            case 0:
                /* Safer not to byteswap, but probably wrong */
                break;
            default:
                qerror("unknow trailer type given its size %d\n", trailer->msgh_trailer_size);
                break;
        }
    }

    /* Special message handling */
    switch (msg_id) {
        case 200: /* host_info */
        {
            mig_reply_error_t *err = (mig_reply_error_t *)hdr;
            struct {
                uint32_t unknow1;
                uint32_t max_cpus;
                uint32_t avail_cpus;
                uint32_t memory_size;
                uint32_t cpu_type;
                uint32_t cpu_subtype;
            } *data = (void *)(err+1);

            DPRINTF("maxcpu = 0x%x\n",   data->max_cpus);
            DPRINTF("numcpu = 0x%x\n",   data->avail_cpus);
            DPRINTF("memsize = 0x%x\n",  data->memory_size);

#if defined(TARGET_I386)
            data->cpu_type = CPU_TYPE_I386;
            DPRINTF("cpu_type changed to 0x%x(i386)\n", data->cpu_type);
            data->cpu_subtype = CPU_SUBTYPE_PENT;
            DPRINTF("cpu_subtype changed to 0x%x(i386_pent)\n", data->cpu_subtype);
#elif defined(TARGET_PPC)
            data->cpu_type = CPU_TYPE_POWERPC;
            DPRINTF("cpu_type changed to 0x%x(ppc)\n", data->cpu_type);
            data->cpu_subtype = CPU_SUBTYPE_POWERPC_750;
            DPRINTF("cpu_subtype changed to 0x%x(ppc_all)\n", data->cpu_subtype);
#else
# error target not supported
#endif
            break;
        }
        case 202: /* host_page_size */
        {
            mig_reply_error_t *err = (mig_reply_error_t *)hdr;
            uint32_t *pagesize = (uint32_t *)(err+1);

            DPRINTF("pagesize = %d\n", *pagesize);
            break;
        }
        default: break;
    }

    swap_mach_msg(hdr, bswap_out);

    return ret;
}