1 //===-- MachException.h -----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Created by Greg Clayton on 6/18/07. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef __MachException_h__ 15 #define __MachException_h__ 16 17 #include <mach/mach.h> 18 #include <vector> 19 20 class MachProcess; 21 class PThreadMutex; 22 23 typedef union MachMessageTag { 24 mach_msg_header_t hdr; 25 char data[1024]; 26 } MachMessage; 27 28 class MachException { 29 public: 30 struct PortInfo { 31 exception_mask_t mask; // the exception mask for this device which may be a 32 // subset of EXC_MASK_ALL... 33 exception_mask_t masks[EXC_TYPES_COUNT]; 34 mach_port_t ports[EXC_TYPES_COUNT]; 35 exception_behavior_t behaviors[EXC_TYPES_COUNT]; 36 thread_state_flavor_t flavors[EXC_TYPES_COUNT]; 37 mach_msg_type_number_t count; 38 39 kern_return_t Save(task_t task); 40 kern_return_t Restore(task_t task); 41 }; 42 43 struct Data { 44 task_t task_port; 45 thread_t thread_port; 46 exception_type_t exc_type; 47 std::vector<mach_exception_data_type_t> exc_data; 48 Data() 49 : task_port(TASK_NULL), thread_port(THREAD_NULL), exc_type(0), 50 exc_data() {} 51 52 void Clear() { 53 task_port = TASK_NULL; 54 thread_port = THREAD_NULL; 55 exc_type = 0; 56 exc_data.clear(); 57 } 58 bool IsValid() const { 59 return task_port != TASK_NULL && thread_port != THREAD_NULL && 60 exc_type != 0; 61 } 62 // Return the SoftSignal for this MachException data, or zero if there is 63 // none 64 int SoftSignal() const { 65 if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 && 66 exc_data[0] == EXC_SOFT_SIGNAL) 67 return static_cast<int>(exc_data[1]); 68 return 0; 69 } 70 bool IsBreakpoint() const { 71 return (exc_type == EXC_BREAKPOINT || 72 ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1)); 73 } 74 void AppendExceptionData(mach_exception_data_t Data, 75 mach_msg_type_number_t Count) { 76 mach_exception_data_type_t Buf; 77 for (mach_msg_type_number_t i = 0; i < Count; ++i) { 78 // Perform an unaligned copy. 79 memcpy(&Buf, Data + i, sizeof(mach_exception_data_type_t)); 80 exc_data.push_back(Buf); 81 } 82 } 83 void Dump() const; 84 void DumpStopReason() const; 85 bool GetStopInfo(struct DNBThreadStopInfo *stop_info) const; 86 }; 87 88 struct Message { 89 MachMessage exc_msg; 90 MachMessage reply_msg; 91 Data state; 92 93 Message() : state() { 94 memset(&exc_msg, 0, sizeof(exc_msg)); 95 memset(&reply_msg, 0, sizeof(reply_msg)); 96 } 97 bool CatchExceptionRaise(task_t task); 98 void Dump() const; 99 kern_return_t Reply(MachProcess *process, int signal); 100 kern_return_t Receive(mach_port_t receive_port, mach_msg_option_t options, 101 mach_msg_timeout_t timeout, 102 mach_port_t notify_port = MACH_PORT_NULL); 103 104 typedef std::vector<Message> collection; 105 typedef collection::iterator iterator; 106 typedef collection::const_iterator const_iterator; 107 }; 108 109 enum { 110 e_actionForward, // Forward signal to inferior process 111 e_actionStop, // Stop when this signal is received 112 }; 113 struct Action { 114 task_t task_port; // Set to TASK_NULL for any TASK 115 thread_t thread_port; // Set to THREAD_NULL for any thread 116 exception_type_t exc_mask; // Mach exception mask to watch for 117 std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to 118 // exception data, or 119 // empty to ignore 120 // exc_data value for 121 // exception 122 std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare 123 // to exception data 124 // after masking, or 125 // empty to ignore 126 // exc_data value 127 // for exception 128 uint8_t flags; // Action flags describing what to do with the exception 129 }; 130 static const char *Name(exception_type_t exc_type); 131 }; 132 133 #endif 134