void GC_attach_current_thread_exceptions_to_handler() { mach_port_t thread_self, exc_port_s; mach_msg_type_name_t type; kern_return_t retval; if (!task_self) return; /* get ids for ourself */ thread_self = mach_thread_self(); /* extract out the send rights for that port, which the OS needs */ retval = mach_port_extract_right(task_self, exc_port, MACH_MSG_TYPE_MAKE_SEND, &exc_port_s, &type); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't extract send rights: %s\n", mach_error_string(retval)); abort(); } /* set the exception ports for this thread to the above */ retval = thread_set_exception_ports(thread_self, EXC_MASK_BAD_ACCESS, exc_port_s, EXCEPTION_DEFAULT, ARCH_THREAD_STATE); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval)); abort(); } #if defined(MZ_USE_PLACES) register_mach_thread(); #endif }
error_t setup_extract_target (void) { error_t err; mach_port_t request; mach_msg_type_name_t requestType; err = mach_port_extract_right (extract_target_task, extract_target_port, extract_target_type, &request, &requestType); if (err) error (1, err, "mach_port_extract_right"); if (err) return err; requestType = MACH_MSG_TYPE_COPY_SEND; return setup (request, requestType); }
bool inferior_namespace_mach_port_num (task_t task, thread_t examine_threads_port, thread_t *inferior_port) { kern_return_t retval; mach_port_name_array_t names; mach_msg_type_number_t nameslen; mach_port_type_array_t types; mach_msg_type_number_t typeslen; if (inferior_port == NULL) return false; retval = mach_port_names (task, &names, &nameslen, &types, &typeslen); if (retval != KERN_SUCCESS) { printf ("Error - unable to get mach port names for inferior.\n"); return false; } int i = 0; for (i = 0; i < nameslen; i++) { mach_port_t local_name; mach_msg_type_name_t local_type; retval = mach_port_extract_right (task, names[i], MACH_MSG_TYPE_COPY_SEND, &local_name, &local_type); if (retval == KERN_SUCCESS) { mach_port_deallocate (mach_task_self(), local_name); if (local_name == examine_threads_port) { *inferior_port = names[i]; vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t)); vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t)); return true; } } } vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t)); vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t)); return false; }
int main( void ) { int i, n_queue; int s, r; mach_port_t destination; kern_return_t err; err = mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_RECEIVE,&destination ); mach_port_insert_right(mach_task_self(), destination, destination, MACH_MSG_TYPE_MAKE_SEND); printf("THE PORT IS %d.\n", destination); send_integer( destination, 9999 ); mach_msg_type_name_t desired; err = mach_port_extract_right(mach_task_self(), destination, MACH_MSG_TYPE_PORT_RECEIVE, &destination, &desired); if (err) { error(1, err, "in mach_port_extract"); } while (1); mach_port_deallocate( mach_task_self(), destination ); return(r); }
/* Translate the port FROM between the tasks in X, returning the translated name in TO, and the types of TO in TO_TYPE, or an error. If TYPE is non-zero, it should be what mach_port_type returns for FROM. */ error_t port_name_xlator_xlate (struct port_name_xlator *x, mach_port_t from, mach_port_type_t from_type, mach_port_t *to, mach_port_type_t *to_type) { error_t err; mach_port_t port; mach_msg_type_number_t i; mach_msg_type_name_t aquired_type; mach_msg_type_name_t valid_to_types; if (from_type == 0) { error_t err = mach_port_type (x->from_task, from, &from_type); if (err) return err; } if (from_type & MACH_PORT_TYPE_RECEIVE) valid_to_types = MACH_PORT_TYPE_SEND; else if (from_type & MACH_PORT_TYPE_SEND) valid_to_types = MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_RECEIVE; else return EKERN_INVALID_RIGHT; /* Translate the name FROM, in FROM_TASK's namespace into our namespace. */ err = mach_port_extract_right (x->from_task, from, ((from_type & MACH_PORT_TYPE_RECEIVE) ? MACH_MSG_TYPE_MAKE_SEND : MACH_MSG_TYPE_COPY_SEND), &port, &aquired_type); if (err) return err; /* Look for likely candidates in TO_TASK's namespace to test against PORT. */ for (i = 0; i < x->to_names_len; i++) { if (x->ports[i] == MACH_PORT_NULL && (x->to_types[i] & valid_to_types)) /* Port I shows possibilities... */ { err = mach_port_extract_right (x->to_task, x->to_names[i], ((x->to_types[i] & MACH_PORT_TYPE_RECEIVE) ? MACH_MSG_TYPE_MAKE_SEND : MACH_MSG_TYPE_COPY_SEND), &x->ports[i], &aquired_type); if (err) x->to_types[i] = 0; /* Don't try to fetch this port again. */ } if (x->ports[i] == port) /* We win! Port I in TO_TASK is the same as PORT. */ break; } mach_port_deallocate (mach_task_self (), port); if (i < x->to_names_len) /* Port I is the right translation; return its name in TO_TASK. */ { *to = x->to_names[i]; *to_type = x->to_types[i]; return 0; } else return EKERN_INVALID_NAME; }
static si_async_workunit_t * si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context) { si_async_workunit_t *r; kern_return_t status; mach_port_t reply, send; mach_msg_type_name_t type; char *s1, *s2, *s3; s1 = NULL; s2 = NULL; s3 = NULL; if (si_call_str1_is_buffer(call)) { if (num3 > 0) { s1 = calloc(1, num3); if (s1 == NULL) return NULL; memcpy(s1, str1, num3); } } else if (str1 != NULL) { s1 = strdup(str1); if (s1 == NULL) return NULL; } if (str2 != NULL) { s2 = strdup(str2); if (s2 == NULL) { if (s1 != NULL) free(s1); return NULL; } } if (str3 != NULL) { s3 = strdup(str3); if (s3 == NULL) { if (s1 != NULL) free(s1); if (s2 != NULL) free(s2); return NULL; } } r = (si_async_workunit_t *)calloc(1, sizeof(si_async_workunit_t)); if (r == NULL) { if (s1 != NULL) free(s1); if (s2 != NULL) free(s2); if (s3 != NULL) free(s3); return NULL; } reply = MACH_PORT_NULL; send = MACH_PORT_NULL; type = 0; status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &reply); if (status == KERN_SUCCESS) status = mach_port_extract_right(mach_task_self(), reply, MACH_MSG_TYPE_MAKE_SEND_ONCE, &send, &type); if (status != KERN_SUCCESS) { if (reply != MACH_PORT_NULL) mach_port_mod_refs(mach_task_self(), reply, MACH_PORT_RIGHT_RECEIVE, -1); if (s1 != NULL) free(s1); if (s2 != NULL) free(s2); if (s3 != NULL) free(s3); free(r); return NULL; } r->si = si; r->call = call; r->str1 = s1; r->str2 = s2; r->str3 = s3; r->num1 = num1; r->num2 = num2; r->num3 = num3; r->num4 = num4; r->refcount = 2; r->flags = 0; if (si_call_returns_list(call)) r->flags |= WORKUNIT_RETURNS_LIST; r->callback = callback; r->context = context; r->port = reply; r->send = send; si_async_worklist_add_unit(r); return r; }
/* this initializes the subsystem (sets the exception port, starts the exception handling thread, etc) */ static void macosx_init_exception_handler() { mach_port_t thread_self, exc_port_s; mach_msg_type_name_t type; kern_return_t retval; /* get ids for ourself */ if(!task_self) task_self = mach_task_self(); thread_self = mach_thread_self(); /* allocate the port we're going to get exceptions on */ retval = mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, &exc_port); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't allocate exception port: %s\n", mach_error_string(retval)); abort(); } /* extract out the send rights for that port, which the OS needs */ retval = mach_port_extract_right(task_self, exc_port, MACH_MSG_TYPE_MAKE_SEND, &exc_port_s, &type); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't extract send rights: %s\n", mach_error_string(retval)); abort(); } /* set the exception ports for this thread to the above */ retval = thread_set_exception_ports(thread_self, EXC_MASK_BAD_ACCESS, exc_port_s, EXCEPTION_DEFAULT, ARCH_THREAD_STATE); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval)); abort(); } #ifdef PPC_HAND_ROLLED_THREAD /* Old hand-rolled thread creation. pthread_create is fine for our purposes. */ { /* set up the subthread */ mach_port_t exc_thread; ARCH_thread_state_t *exc_thread_state; void *subthread_stack; retval = thread_create(task_self, &exc_thread); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't create exception thread: %s\n", mach_error_string(retval)); abort(); } subthread_stack = (void*)malloc(page_size); subthread_stack += (page_size - C_ARGSAVE_LEN - C_RED_ZONE); exc_thread_state = (ARCH_thread_state_t*)malloc(sizeof(ARCH_thread_state_t)); exc_thread_state->srr0 = (unsigned int)exception_thread; exc_thread_state->r1 = (unsigned int)subthread_stack; retval = thread_set_state(exc_thread, ARCH_THREAD_STATE, (thread_state_t)exc_thread_state, ARCH_THREAD_STATE_COUNT); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't set subthread state: %s\n", mach_error_string(retval)); abort(); } retval = thread_resume(exc_thread); if(retval != KERN_SUCCESS) { GCPRINT(GCOUTF, "Couldn't resume subthread: %s\n", mach_error_string(retval)); abort(); } } #else { pthread_t th; pthread_create(&th, NULL, (void *(*)(void *))exception_thread, NULL); } #endif }
static int mach_setup(int launchd_flag) { mach_msg_type_name_t poly; /* * Allocate a port set. */ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &port_set) != KERN_SUCCESS) { auditd_log_err("Allocation of port set failed"); return (-1); } /* * Allocate a signal reflection port. */ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &signal_port) != KERN_SUCCESS || mach_port_move_member(mach_task_self(), signal_port, port_set) != KERN_SUCCESS) { auditd_log_err("Allocation of signal port failed"); return (-1); } /* * Allocate a trigger port. */ if (launchd_flag) { /* * If started under launchd, lookup port in launchd dictionary. */ if ((control_port = lookup_machport(__AUDIT_LAUNCHD_LABEL)) == MACH_PORT_NULL || mach_port_move_member(mach_task_self(), control_port, port_set) != KERN_SUCCESS) { auditd_log_err("Cannot get Mach control port" " via launchd"); return (-1); } else auditd_log_debug("Mach control port registered" " via launchd"); } else { /* * If not started under launchd, allocate port and register. */ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &control_port) != KERN_SUCCESS || mach_port_move_member(mach_task_self(), control_port, port_set) != KERN_SUCCESS) auditd_log_err("Allocation of trigger port failed"); /* * Create a send right on our trigger port. */ mach_port_extract_right(mach_task_self(), control_port, MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly); /* * Register the trigger port with the kernel. */ if (host_set_audit_control_port(mach_host_self(), control_port) != KERN_SUCCESS) { auditd_log_err("Cannot set Mach control port"); return (-1); } else auditd_log_debug("Mach control port registered"); } return (0); }