debug.c
1 #include <darlingserver/duct-tape.h> 2 #include <darlingserver/duct-tape/task.h> 3 4 uint64_t dtape_debug_task_port_count(dtape_task_t* task) { 5 return task->xnu_task.itk_space->is_table_hashed; 6 }; 7 8 uint64_t dtape_debug_task_list_ports(dtape_task_t* task, dtape_debug_task_list_ports_iterator_f iterator, void* context) { 9 uint64_t port_count = 0; 10 bool call_it = true; 11 12 for (mach_port_index_t index = 0; index < task->xnu_task.itk_space->is_table_size; ++index) { 13 ipc_entry_t entry = &task->xnu_task.itk_space->is_table[index]; 14 dtape_debug_port_t debug_port; 15 ipc_port_t port = NULL; 16 17 if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE) { 18 continue; 19 } 20 21 port = ip_object_to_port(entry->ie_object); 22 23 debug_port.name = MACH_PORT_MAKE(index, IE_BITS_GEN(entry->ie_bits)); 24 debug_port.refs = IE_BITS_UREFS(entry->ie_bits); 25 debug_port.rights = IE_BITS_TYPE(entry->ie_bits); 26 debug_port.messages = port->ip_messages.imq_msgcount; 27 28 if (call_it) { 29 call_it = iterator(context, &debug_port); 30 } 31 32 ++port_count; 33 } 34 35 return port_count; 36 }; 37 38 uint64_t dtape_debug_portset_list_members(dtape_task_t* task, uint32_t portset, dtape_debug_portset_list_members_iterator_f iterator, void* context) { 39 ipc_object_t object = NULL; 40 ipc_mqueue_t mqueue = NULL; 41 ipc_entry_num_t member_count = 0; 42 mach_port_name_t* names = NULL; 43 ipc_entry_num_t actual_count = 0; 44 bool call_it = true; 45 46 if (ipc_mqueue_copyin(task->xnu_task.itk_space, portset, &mqueue, &object) != KERN_SUCCESS) { 47 return 0; 48 } 49 50 do { 51 if (names) { 52 kfree(names, sizeof(*names) * member_count); 53 } 54 55 names = kalloc(sizeof(*names) * actual_count); 56 member_count = actual_count; 57 58 ipc_mqueue_set_gather_member_names(task->xnu_task.itk_space, mqueue, member_count, names, &actual_count); 59 } while (member_count != actual_count); 60 61 for (ipc_entry_num_t i = 0; i < member_count; ++i) { 62 mach_port_name_t* name = &names[i]; 63 dtape_debug_port_t debug_port; 64 ipc_entry_t entry = NULL; 65 ipc_port_t port = NULL; 66 67 entry = ipc_entry_lookup(task->xnu_task.itk_space, *name); 68 port = ip_object_to_port(entry->ie_object); 69 70 debug_port.name = *name; 71 debug_port.refs = IE_BITS_UREFS(entry->ie_bits); 72 debug_port.rights = IE_BITS_TYPE(entry->ie_bits); 73 debug_port.messages = port->ip_messages.imq_msgcount; 74 75 if (call_it) { 76 call_it = iterator(context, &debug_port); 77 } 78 } 79 80 if (names) { 81 kfree(names, sizeof(*names) * member_count); 82 } 83 84 io_release(object); 85 86 return member_count; 87 }; 88 89 uint64_t dtape_debug_port_list_messages(dtape_task_t* task, uint32_t port, dtape_debug_port_list_messages_iterator_f iterator, void* context) { 90 ipc_object_t object = NULL; 91 ipc_mqueue_t mqueue = NULL; 92 uint64_t message_count = 0; 93 bool call_it = true; 94 95 if (ipc_mqueue_copyin(task->xnu_task.itk_space, port, &mqueue, &object) != KERN_SUCCESS) { 96 return 0; 97 } 98 99 for (ipc_kmsg_t kmsg = ipc_kmsg_queue_first(&mqueue->imq_messages); kmsg != NULL; kmsg = ipc_kmsg_queue_next(&mqueue->imq_messages, kmsg)) { 100 dtape_debug_message_t debug_message; 101 102 debug_message.sender = 0; 103 104 if (kmsg->ikm_header->msgh_remote_port && kmsg->ikm_header->msgh_remote_port->ip_receiver) { 105 debug_message.sender = dtape_task_for_xnu_task(kmsg->ikm_header->msgh_remote_port->ip_receiver->is_task)->saved_pid; 106 } 107 108 debug_message.size = kmsg->ikm_size; 109 110 if (call_it) { 111 call_it = iterator(context, &debug_message); 112 } 113 114 ++message_count; 115 } 116 117 io_release(object); 118 119 return message_count; 120 };