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 15 #ifndef __MachException_h__ 16 #define __MachException_h__ 17 18 #include <mach/mach.h> 19 #include <vector> 20 #include "DNBConfig.h" 21 22 #ifdef HAVE_64_BIT_MACH_EXCEPTIONS 23 24 #define MACH_EXCEPTION_DATA_FMT_DEC "%lld" 25 #define MACH_EXCEPTION_DATA_FMT_HEX "0x%16.16llx" 26 #define MACH_EXCEPTION_DATA_FMT_MINHEX "0x%llx" 27 28 #else 29 30 #define MACH_EXCEPTION_DATA_FMT_DEC "%d" 31 #define MACH_EXCEPTION_DATA_FMT_HEX "0x%8.8x" 32 #define MACH_EXCEPTION_DATA_FMT_MINHEX "0x%x" 33 34 #endif 35 36 class MachProcess; 37 class PThreadMutex; 38 39 typedef union MachMessageTag 40 { 41 mach_msg_header_t hdr; 42 char data[1024]; 43 } MachMessage; 44 45 46 class MachException 47 { 48 public: 49 50 struct PortInfo 51 { 52 exception_mask_t masks[EXC_TYPES_COUNT]; 53 mach_port_t ports[EXC_TYPES_COUNT]; 54 exception_behavior_t behaviors[EXC_TYPES_COUNT]; 55 thread_state_flavor_t flavors[EXC_TYPES_COUNT]; 56 mach_msg_type_number_t count; 57 58 kern_return_t Save(task_t task); 59 kern_return_t Restore(task_t task); 60 }; 61 62 struct Data 63 { 64 task_t task_port; 65 thread_t thread_port; 66 exception_type_t exc_type; 67 std::vector<mach_exception_data_type_t> exc_data; 68 Data() : 69 task_port(TASK_NULL), 70 thread_port(THREAD_NULL), 71 exc_type(0), 72 exc_data() 73 { 74 } 75 76 void Clear() 77 { 78 task_port = TASK_NULL; 79 thread_port = THREAD_NULL; 80 exc_type = 0; 81 exc_data.clear(); 82 } 83 bool IsValid() const 84 { 85 return task_port != TASK_NULL && 86 thread_port != THREAD_NULL && 87 exc_type != 0; 88 } 89 // Return the SoftSignal for this MachException data, or zero if there is none 90 int SoftSignal() const 91 { 92 if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 && exc_data[0] == EXC_SOFT_SIGNAL) 93 return exc_data[1]; 94 return 0; 95 } 96 bool IsBreakpoint() const 97 { 98 return (exc_type == EXC_BREAKPOINT) || ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1); 99 } 100 void Dump() const; 101 void DumpStopReason() const; 102 bool GetStopInfo(struct DNBThreadStopInfo *stop_info) const; 103 }; 104 105 struct Message 106 { 107 MachMessage exc_msg; 108 MachMessage reply_msg; 109 Data state; 110 111 Message() : 112 state() 113 { 114 memset(&exc_msg, 0, sizeof(exc_msg)); 115 memset(&reply_msg, 0, sizeof(reply_msg)); 116 } 117 bool CatchExceptionRaise(); 118 void Dump() const; 119 kern_return_t Reply (MachProcess *process, int signal); 120 kern_return_t Receive( mach_port_t receive_port, 121 mach_msg_option_t options, 122 mach_msg_timeout_t timeout, 123 mach_port_t notify_port = MACH_PORT_NULL); 124 125 typedef std::vector<Message> collection; 126 typedef collection::iterator iterator; 127 typedef collection::const_iterator const_iterator; 128 }; 129 130 enum 131 { 132 e_actionForward, // Forward signal to inferior process 133 e_actionStop, // Stop when this signal is received 134 }; 135 struct Action 136 { 137 task_t task_port; // Set to TASK_NULL for any TASK 138 thread_t thread_port; // Set to THREAD_NULL for any thread 139 exception_type_t exc_mask; // Mach exception mask to watch for 140 std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to exception data, or empty to ignore exc_data value for exception 141 std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare to exception data after masking, or empty to ignore exc_data value for exception 142 uint8_t flags; // Action flags describing what to do with the exception 143 }; 144 static const char *Name(exception_type_t exc_type); 145 }; 146 147 #endif 148