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