1061da546Spatrick //===-- MachException.h -----------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick // 9061da546Spatrick // Created by Greg Clayton on 6/18/07. 10061da546Spatrick // 11061da546Spatrick //===----------------------------------------------------------------------===// 12061da546Spatrick 13dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHEXCEPTION_H 14dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHEXCEPTION_H 15061da546Spatrick 16061da546Spatrick #include <mach/mach.h> 17061da546Spatrick #include <vector> 18061da546Spatrick 19061da546Spatrick class MachProcess; 20061da546Spatrick class PThreadMutex; 21061da546Spatrick 22061da546Spatrick typedef union MachMessageTag { 23061da546Spatrick mach_msg_header_t hdr; 24061da546Spatrick char data[1024]; 25061da546Spatrick } MachMessage; 26061da546Spatrick 27061da546Spatrick class MachException { 28061da546Spatrick public: 29061da546Spatrick struct PortInfo { 30061da546Spatrick exception_mask_t mask; // the exception mask for this device which may be a 31061da546Spatrick // subset of EXC_MASK_ALL... 32061da546Spatrick exception_mask_t masks[EXC_TYPES_COUNT]; 33061da546Spatrick mach_port_t ports[EXC_TYPES_COUNT]; 34061da546Spatrick exception_behavior_t behaviors[EXC_TYPES_COUNT]; 35061da546Spatrick thread_state_flavor_t flavors[EXC_TYPES_COUNT]; 36061da546Spatrick mach_msg_type_number_t count; 37061da546Spatrick 38061da546Spatrick kern_return_t Save(task_t task); 39061da546Spatrick kern_return_t Restore(task_t task); 40061da546Spatrick }; 41061da546Spatrick 42061da546Spatrick struct Data { 43061da546Spatrick task_t task_port; 44061da546Spatrick thread_t thread_port; 45061da546Spatrick exception_type_t exc_type; 46061da546Spatrick std::vector<mach_exception_data_type_t> exc_data; DataData47061da546Spatrick Data() 48061da546Spatrick : task_port(TASK_NULL), thread_port(THREAD_NULL), exc_type(0), 49061da546Spatrick exc_data() {} 50061da546Spatrick ClearData51061da546Spatrick void Clear() { 52061da546Spatrick task_port = TASK_NULL; 53061da546Spatrick thread_port = THREAD_NULL; 54061da546Spatrick exc_type = 0; 55061da546Spatrick exc_data.clear(); 56061da546Spatrick } IsValidData57061da546Spatrick bool IsValid() const { 58061da546Spatrick return task_port != TASK_NULL && thread_port != THREAD_NULL && 59061da546Spatrick exc_type != 0; 60061da546Spatrick } 61061da546Spatrick // Return the SoftSignal for this MachException data, or zero if there is 62061da546Spatrick // none SoftSignalData63061da546Spatrick int SoftSignal() const { 64061da546Spatrick if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 && 65061da546Spatrick exc_data[0] == EXC_SOFT_SIGNAL) 66061da546Spatrick return static_cast<int>(exc_data[1]); 67061da546Spatrick return 0; 68061da546Spatrick } IsBreakpointData69061da546Spatrick bool IsBreakpoint() const { 70061da546Spatrick return (exc_type == EXC_BREAKPOINT || 71061da546Spatrick ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1)); 72061da546Spatrick } AppendExceptionDataData73061da546Spatrick void AppendExceptionData(mach_exception_data_t Data, 74061da546Spatrick mach_msg_type_number_t Count) { 75061da546Spatrick mach_exception_data_type_t Buf; 76061da546Spatrick for (mach_msg_type_number_t i = 0; i < Count; ++i) { 77061da546Spatrick // Perform an unaligned copy. 78061da546Spatrick memcpy(&Buf, Data + i, sizeof(mach_exception_data_type_t)); 79061da546Spatrick exc_data.push_back(Buf); 80061da546Spatrick } 81061da546Spatrick } 82061da546Spatrick void Dump() const; 83061da546Spatrick void DumpStopReason() const; 84061da546Spatrick bool GetStopInfo(struct DNBThreadStopInfo *stop_info) const; 85061da546Spatrick }; 86061da546Spatrick 87061da546Spatrick struct Message { 88061da546Spatrick MachMessage exc_msg; 89061da546Spatrick MachMessage reply_msg; 90061da546Spatrick Data state; 91061da546Spatrick MessageMessage92061da546Spatrick Message() : state() { 93061da546Spatrick memset(&exc_msg, 0, sizeof(exc_msg)); 94061da546Spatrick memset(&reply_msg, 0, sizeof(reply_msg)); 95061da546Spatrick } 96061da546Spatrick bool CatchExceptionRaise(task_t task); 97061da546Spatrick void Dump() const; 98061da546Spatrick kern_return_t Reply(MachProcess *process, int signal); 99061da546Spatrick kern_return_t Receive(mach_port_t receive_port, mach_msg_option_t options, 100061da546Spatrick mach_msg_timeout_t timeout, 101061da546Spatrick mach_port_t notify_port = MACH_PORT_NULL); 102061da546Spatrick 103061da546Spatrick typedef std::vector<Message> collection; 104061da546Spatrick typedef collection::iterator iterator; 105061da546Spatrick typedef collection::const_iterator const_iterator; 106061da546Spatrick }; 107061da546Spatrick 108061da546Spatrick enum { 109061da546Spatrick e_actionForward, // Forward signal to inferior process 110061da546Spatrick e_actionStop, // Stop when this signal is received 111061da546Spatrick }; 112061da546Spatrick struct Action { 113061da546Spatrick task_t task_port; // Set to TASK_NULL for any TASK 114061da546Spatrick thread_t thread_port; // Set to THREAD_NULL for any thread 115061da546Spatrick exception_type_t exc_mask; // Mach exception mask to watch for 116061da546Spatrick std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to 117061da546Spatrick // exception data, or 118061da546Spatrick // empty to ignore 119061da546Spatrick // exc_data value for 120061da546Spatrick // exception 121061da546Spatrick std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare 122061da546Spatrick // to exception data 123061da546Spatrick // after masking, or 124061da546Spatrick // empty to ignore 125061da546Spatrick // exc_data value 126061da546Spatrick // for exception 127061da546Spatrick uint8_t flags; // Action flags describing what to do with the exception 128061da546Spatrick }; 129061da546Spatrick static const char *Name(exception_type_t exc_type); 130*f6aab3d8Srobert static exception_mask_t ExceptionMask(const char *name); 131061da546Spatrick }; 132061da546Spatrick 133061da546Spatrick #endif 134