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