#ifndef _MACH_RPC_H_
#define _MACH_RPC_H_
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/port.h>
#include <mach/vm_types.h>
#include <mach/mig.h>
#include <mach/mig_errors.h>
#include <mach/machine/rpc.h>
#include <mach/thread_status.h>
#ifdef MACH_KERNEL_PRIVATE
#include <ipc/ipc_object.h>
#endif
#define TYPE_SHIFT 0
#define MACH_RPC_PORT (1 << TYPE_SHIFT)
#define MACH_RPC_ARRAY (1 << (TYPE_SHIFT + 1))
#define MACH_RPC_VARIABLE (1 << (TYPE_SHIFT + 2))
#define LAST_TYPE_BIT (TYPE_SHIFT+3)
#define MACH_RPC_ARRAY_FIX (MACH_RPC_ARRAY)
#define MACH_RPC_ARRAY_FIXED (MACH_RPC_ARRAY)
#define MACH_RPC_ARRAY_VAR (MACH_RPC_ARRAY | MACH_RPC_VARIABLE)
#define MACH_RPC_ARRAY_VARIABLE (MACH_RPC_ARRAY | MACH_RPC_VARIABLE)
#define MACH_RPC_PORT_ARRAY (MACH_RPC_PORT | MACH_RPC_ARRAY_VAR)
#define DIRECT_SHIFT LAST_TYPE_BIT
#define DIRECTION_SHIFT LAST_TYPE_BIT
#define MACH_RPC_IN (1 << DIRECTION_SHIFT)
#define MACH_RPC_OUT (1 << (DIRECTION_SHIFT + 1))
#define LAST_DIRECT_BIT (DIRECTION_SHIFT + 2)
#define LAST_DIRECTION_BIT (DIRECTION_SHIFT + 2)
#define MACH_RPC_INOUT (MACH_RPC_IN | MACH_RPC_OUT)
#define POINTER_SHIFT LAST_DIRECTION_BIT
#define MACH_RPC_POINTER (1 << POINTER_SHIFT)
#define LAST_POINTER_BIT (POINTER_SHIFT + 1)
#define NAME_SHIFT LAST_POINTER_BIT
#define MACH_RPC_RECEIVE (1 << NAME_SHIFT)
#define MACH_RPC_SEND (2 << NAME_SHIFT)
#define MACH_RPC_SEND_ONCE (3 << NAME_SHIFT)
#define LAST_NAME_BIT (NAME_SHIFT + 2)
#define ACTION_SHIFT LAST_NAME_BIT
#define MACH_RPC_MOVE (1 << ACTION_SHIFT)
#define MACH_RPC_COPY (2 << ACTION_SHIFT)
#define MACH_RPC_MAKE (3 << ACTION_SHIFT)
#define LAST_ACTION_BIT (ACTION_SHIFT + 2)
#define MACH_RPC_MOVE_RECEIVE (MACH_RPC_MOVE | MACH_RPC_RECEIVE)
#define MACH_RPC_MOVE_SEND (MACH_RPC_MOVE | MACH_RPC_SEND)
#define MACH_RPC_COPY_SEND (MACH_RPC_COPY | MACH_RPC_SEND)
#define MACH_RPC_MAKE_SEND (MACH_RPC_MAKE | MACH_RPC_SEND)
#define MACH_RPC_MOVE_SEND_ONCE (MACH_RPC_MOVE | MACH_RPC_SEND_ONCE)
#define MACH_RPC_MAKE_SEND_ONCE (MACH_RPC_MAKE | MACH_RPC_SEND_ONCE)
#define OPTION_SHIFT LAST_ACTION_BIT
#define MACH_RPC_PHYSICAL_COPY (1 << OPTION_SHIFT)
#define MACH_RPC_VIRTUAL_COPY (1 << (OPTION_SHIFT + 1))
#define LAST_OPTION_BIT (OPTION_SHIFT + 2)
#define DEALLOCATE_SHIFT LAST_OPTION_BIT
#define MACH_RPC_DEALLOCATE (1 << DEALLOCATE_SHIFT)
#define LAST_DEALLOCATE_BIT (DEALLOCATE_SHIFT + 1)
#define ONSTACK_SHIFT LAST_DEALLOCATE_BIT
#define MACH_RPC_ONSTACK (1 << ONSTACK_SHIFT)
#define LAST_ONSTACK_BIT (ONSTACK_SHIFT + 1)
#define BOUND_SHIFT LAST_ONSTACK_BIT
#define MACH_RPC_BOUND (1 << BOUND_SHIFT)
#define MACH_RPC_UNBOUND (0)
#define BOUND MACH_RPC_BOUND
#define UNBND MACH_RPC_UNBOUND
#define LAST_BOUND_BIT (BOUND_SHIFT + 1)
typedef unsigned int routine_arg_type;
typedef unsigned int routine_arg_offset;
typedef unsigned int routine_arg_size;
struct routine_arg_descriptor {
routine_arg_type type;
routine_arg_size size;
routine_arg_size count;
routine_arg_offset offset;
};
typedef struct routine_arg_descriptor *routine_arg_descriptor_t;
struct routine_descriptor {
mig_impl_routine_t impl_routine;
mig_stub_routine_t stub_routine;
unsigned int argc;
unsigned int descr_count;
struct routine_arg_descriptor *
arg_descr;
unsigned int max_reply_msg;
};
typedef struct routine_descriptor *routine_descriptor_t;
#define DESCR_SIZE(x) ((x)->descr_count * sizeof(struct routine_arg_descriptor))
struct rpc_signature {
struct routine_descriptor rd;
struct routine_arg_descriptor rad[1];
};
#ifdef MACH_KERNEL_PRIVATE
typedef struct rpc_signature *rpc_signature_t;
#endif
#define RPC_SIGBUF_SIZE 8
struct rpc_subsystem {
struct subsystem *subsystem;
mach_msg_id_t start;
mach_msg_id_t end;
unsigned int maxsize;
vm_address_t base_addr;
struct routine_descriptor
routine[1
];
struct routine_arg_descriptor
arg_descriptor[1
];
};
typedef struct rpc_subsystem *rpc_subsystem_t;
#define RPC_SUBSYSTEM_NULL ((rpc_subsystem_t) 0)
#define RPC_MASK(shift,last) \
( ((1 << ((last)-(shift)))-1) << (shift) )
#define RPC_FIELD(field,shift,last) \
( (field) & (((1 << ((last)-(shift)))-1) << (shift)) )
#define RPC_BOUND(dsc) \
(((RPC_FIELD((dsc).type,TYPE_SHIFT+1,TYPE_SHIFT+3) == \
MACH_RPC_ARRAY_VARIABLE) && (dsc).count != 0) ? MACH_RPC_BOUND : 0)
#define ROUNDUP2(x,n) ((((unsigned)(x)) + (n) - 1) & ~((n)-1))
#define ROUNDWORD(x) ROUNDUP2(x,sizeof(int))
#define MACH_RPC_DEBUG 1
#define ERR_INFO 1
#define ERR_GREEN 2
#define ERR_YELLOW 3
#define ERR_RED 4
#define ERR_FATAL 5
#if MACH_RPC_DEBUG > 1
#define rpc_error(E,S) \
printf("RPC error "); \
rpc_error_show_severity(S); \
printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \
printf E ; \
printf("\n"); \
rpc_error_severity(S)
#else
#define rpc_error(E,S) \
if ((S) == ERR_FATAL || (S) == ERR_RED) { \
printf("RPC error "); \
rpc_error_show_severity(S); \
printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \
printf E ; \
printf("\n"); \
rpc_error_severity(S); \
}
#endif
#define RPC_KBUF_SIZE 16
#define RPC_COW_SIZE 1024
#define RPC_DESC_COUNT 4
#define COPY_TYPE_NO_COPY 0
#define COPY_TYPE_ON_KSTACK 1
#define COPY_TYPE_ON_SSTACK 2
#define COPY_TYPE_VIRTUAL_IN 3
#define COPY_TYPE_VIRTUAL_OUT_SVR 4
#define COPY_TYPE_VIRTUAL_OUT_CLN 5
#define COPY_TYPE_ALLOC_KRN 6
#define COPY_TYPE_ALLOC_SVR 7
#define COPY_TYPE_ALLOC_CLN 8
#define COPY_TYPE_PORT 9
#define COPY_TYPE_PORT_ARRAY 10
typedef int rpc_id_t;
typedef int rpc_return_t;
typedef unsigned int rpc_size_t;
typedef unsigned int rpc_offset_t;
struct rpc_copy_state {
unsigned copy_type;
vm_offset_t alloc_addr;
};
typedef struct rpc_copy_state *rpc_copy_state_t;
typedef struct rpc_copy_state rpc_copy_state_data_t;
typedef boolean_t (*copyfunc_t)(const char *, char *, vm_size_t);
#ifdef CALLOUT_RPC_MODEL
extern
void rpc_bootstrap( void );
extern
void rpc_remote_bootstrap( void );
extern
rpc_return_t mach_rpc_trap(
mach_port_name_t dest_port,
rpc_id_t routine_num,
rpc_signature_t signature_ptr,
rpc_size_t signature_size );
extern
rpc_return_t mach_rpc_return_trap( void );
extern
rpc_return_t mach_rpc_return_error( void );
void mach_rpc_return_wrapper( void );
void rpc_upcall(
vm_offset_t stack,
vm_offset_t new_stack,
vm_offset_t server_func,
int return_code );
void rpc_error_severity( int severity );
void rpc_error_show_severity( int severity );
unsigned int name_rpc_to_ipc( unsigned int action );
void clean_port_array(
ipc_object_t * array,
unsigned count,
unsigned cooked,
unsigned direct );
void unwind_rpc_state(
routine_descriptor_t routine,
rpc_copy_state_t state,
int * arg_buf );
kern_return_t unwind_invoke_state(
thread_act_t thr_act );
kern_return_t rpc_invke_args_in(
routine_descriptor_t routine,
rpc_copy_state_t state,
int * arg_buf,
copyfunc_t infunc );
kern_return_t rpc_invke_args_out(
routine_descriptor_t routine,
rpc_copy_state_t state,
int * arg_buf,
int ** new_sp,
copyfunc_t outfunc );
kern_return_t rpc_reply_args_in(
routine_descriptor_t routine,
rpc_copy_state_t state,
int * svr_buf,
copyfunc_t infunc );
kern_return_t rpc_reply_args_out(
routine_descriptor_t routine,
rpc_copy_state_t state,
int * svr_buf,
int * cln_buf,
copyfunc_t outfunc );
#endif
extern rpc_subsystem_t mach_subsystem_join(
rpc_subsystem_t,
rpc_subsystem_t,
unsigned int *,
void *(* )(int));
#endif