xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/MacOSX/MachException.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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