1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(clippy::upper_case_acronyms)]

use enum_primitive_derive::Primitive;

/// Values for
/// [`MINIDUMP_EXCEPTION::exception_code`](crate::format::MINIDUMP_EXCEPTION::exception_code)
/// for crashes on macOS.
///
/// Based on Darwin/macOS' mach/exception_types.h. This is what macOS calls an "exception",
/// not a "code".
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMac {
    /// code can be a kern_return_t
    EXC_BAD_ACCESS = 1,
    /// code is CPU-specific
    EXC_BAD_INSTRUCTION = 2,
    /// code is CPU-specific
    EXC_ARITHMETIC = 3,
    /// code is CPU-specific
    EXC_EMULATION = 4,
    EXC_SOFTWARE = 5,
    /// code is CPU-specific
    EXC_BREAKPOINT = 6,
    EXC_SYSCALL = 7,
    EXC_MACH_SYSCALL = 8,
    EXC_RPC_ALERT = 9,
    EXC_RESOURCE = 11,
    EXC_GUARD = 12,
    /// Fake exception code used by Crashpad's SimulateCrash ('CPsx')
    SIMULATED = 0x43507378,
}

// These error codes are based on
// * mach/ppc/exception.h
// * mach/i386/exception.h

/// Mac/iOS Kernel Bad Access Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadAccessKernType {
    // These are relevant kern_return_t values from mach/kern_return.h
    KERN_INVALID_ADDRESS = 1,
    KERN_PROTECTION_FAILURE = 2,
    KERN_FAILURE = 5,
    KERN_NO_ACCESS = 8,
    KERN_MEMORY_FAILURE = 9,
    KERN_MEMORY_ERROR = 10,
    KERN_CODESIGN_ERROR = 50,
}

/// Mac/iOS Arm Userland Bad Accesses Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadAccessArmType {
    EXC_ARM_DA_ALIGN = 0x0101,
    EXC_ARM_DA_DEBUG = 0x0102,
}

/// Mac/iOS Ppc Userland Bad Access Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadAccessPpcType {
    EXC_PPC_VM_PROT_READ = 0x0101,
    EXC_PPC_BADSPACE = 0x0102,
    EXC_PPC_UNALIGNED = 0x0103,
}

/// Mac/iOS x86 Userland Bad Access Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadAccessX86Type {
    EXC_I386_GPFLT = 13,
}

/// Mac/iOS Arm Bad Instruction Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadInstructionArmType {
    EXC_ARM_UNDEFINED = 1,
}

/// Mac/iOS Ppc Bad Instruction Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadInstructionPpcType {
    EXC_PPC_INVALID_SYSCALL = 1,
    EXC_PPC_UNIPL_INST = 2,
    EXC_PPC_PRIVINST = 3,
    EXC_PPC_PRIVREG = 4,
    EXC_PPC_TRACE = 5,
    EXC_PPC_PERFMON = 6,
}

/// Mac/iOS x86 Bad Instruction Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBadInstructionX86Type {
    /// Invalid Operation
    EXC_I386_INVOP = 1,

    // The rest of these are raw x86 interrupt codes.
    /// Invalid Task State Segment
    EXC_I386_INVTSSFLT = 10,
    /// Segment Not Present
    EXC_I386_SEGNPFLT = 11,
    /// Stack Fault
    EXC_I386_STKFLT = 12,
    /// General Protection Fault
    EXC_I386_GPFLT = 13,
    /// Alignment Fault
    EXC_I386_ALIGNFLT = 17,
    // For sake of completeness, here's the interrupt codes that won't show up here (and why):

    // EXC_I386_DIVERR    =  0: mapped to EXC_ARITHMETIC/EXC_I386_DIV
    // EXC_I386_SGLSTP    =  1: mapped to EXC_BREAKPOINT/EXC_I386_SGL
    // EXC_I386_NMIFLT    =  2: should not occur in user space
    // EXC_I386_BPTFLT    =  3: mapped to EXC_BREAKPOINT/EXC_I386_BPT
    // EXC_I386_INTOFLT   =  4: mapped to EXC_ARITHMETIC/EXC_I386_INTO
    // EXC_I386_BOUNDFLT  =  5: mapped to EXC_ARITHMETIC/EXC_I386_BOUND
    // EXC_I386_INVOPFLT  =  6: mapped to EXC_BAD_INSTRUCTION/EXC_I386_INVOP
    // EXC_I386_NOEXTFLT  =  7: should be handled by the kernel
    // EXC_I386_DBLFLT    =  8: should be handled (if possible) by the kernel
    // EXC_I386_EXTOVRFLT =  9: mapped to EXC_BAD_ACCESS/(PROT_READ|PROT_EXEC)
    // EXC_I386_PGFLT     = 14: should not occur in user space
    // EXC_I386_EXTERRFLT = 16: mapped to EXC_ARITHMETIC/EXC_I386_EXTERR
    // EXC_I386_ENOEXTFLT = 32: should be handled by the kernel
    // EXC_I386_ENDPERR   = 33: should not occur
}

/// Mac/iOS Ppc Arithmetic Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacArithmeticPpcType {
    /// Integer ovrflow
    EXC_PPC_OVERFLOW = 1,
    /// Integer Divide-By-Zero
    EXC_PPC_ZERO_DIVIDE = 2,
    /// Float Inexact
    EXC_FLT_INEXACT = 3,
    /// Float Divide-By-Zero
    EXC_PPC_FLT_ZERO_DIVIDE = 4,
    /// Float Underflow
    EXC_PPC_FLT_UNDERFLOW = 5,
    /// Float Overflow
    EXC_PPC_FLT_OVERFLOW = 6,
    /// Float Not A Number
    EXC_PPC_FLT_NOT_A_NUMBER = 7,

    // NOTE: comments in breakpad suggest these two are actually supposed to be
    // for ExceptionCodeMac::EXC_EMULATION, but for now let's duplicate breakpad.
    EXC_PPC_NOEMULATION = 8,
    EXC_PPC_ALTIVECASSIST = 9,
}

/// Mac/iOS x86 Arithmetic Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacArithmeticX86Type {
    EXC_I386_DIV = 1,
    EXC_I386_INTO = 2,
    EXC_I386_NOEXT = 3,
    EXC_I386_EXTOVR = 4,
    EXC_I386_EXTERR = 5,
    EXC_I386_EMERR = 6,
    EXC_I386_BOUND = 7,
    EXC_I386_SSEEXTERR = 8,
}

/// Mac/iOS "Software" Exceptions
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacSoftwareType {
    SIGABRT = 0x00010002u32,
    UNCAUGHT_NS_EXCEPTION = 0xDEADC0DE,
    EXC_PPC_TRAP = 0x00000001,
    EXC_PPC_MIGRATE = 0x00010100,
    // Breakpad also defines these doesn't use them for Software crashes
    // SIGSYS  = 0x00010000,
    // SIGPIPE = 0x00010001,
}

/// Mac/iOS Arm Breakpoint Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBreakpointArmType {
    EXC_ARM_DA_ALIGN = 0x0101,
    EXC_ARM_DA_DEBUG = 0x0102,
    EXC_ARM_BREAKPOINT = 1,
}

/// Mac/iOS Ppc Breakpoint Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBreakpointPpcType {
    EXC_PPC_BREAKPOINT = 1,
}

/// Mac/iOS x86 Breakpoint Exceptions
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacBreakpointX86Type {
    EXC_I386_SGL = 1,
    EXC_I386_BPT = 2,
}

/// Mac/iOS Resource exception types
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacResourceType {
    RESOURCE_TYPE_CPU = 1,
    RESOURCE_TYPE_WAKEUPS = 2,
    RESOURCE_TYPE_MEMORY = 3,
    RESOURCE_TYPE_IO = 4,
    RESOURCE_TYPE_THREADS = 5,
}

/// Mac/iOS CPU resource exception flavors
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacResourceCpuFlavor {
    FLAVOR_CPU_MONITOR = 1,
    FLAVOR_CPU_MONITOR_FATAL = 2,
}

/// Mac/iOS wakeups resource exception flavors
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacResourceWakeupsFlavor {
    FLAVOR_WAKEUPS_MONITOR = 1,
}

/// Mac/iOS memory resource exception flavors
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacResourceMemoryFlavor {
    FLAVOR_HIGH_WATERMARK = 1,
}

/// Mac/iOS I/O resource exception flavors
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacResourceIOFlavor {
    FLAVOR_IO_PHYSICAL_WRITES = 1,
    FLAVOR_IO_LOGICAL_WRITES = 2,
}

/// Mac/iOS threads resource exception flavors
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacResourceThreadsFlavor {
    FLAVOR_THREADS_HIGH_WATERMARK = 1,
}

/// Mac/iOS Guard exception types
///
/// See the [osfmk/kern/exc_guard.h][header] header in Apple's kernel sources
///
/// [header]: https://github.com/apple/darwin-xnu/blob/main/osfmk/kern/exc_guard.h
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacGuardType {
    GUARD_TYPE_NONE = 0,
    GUARD_TYPE_MACH_PORT = 1,
    GUARD_TYPE_FD = 2,
    GUARD_TYPE_USER = 3,
    GUARD_TYPE_VN = 4,
    GUARD_TYPE_VIRT_MEMORY = 5,
}

/// Mac/iOS Mach port guard exception flavors
///
/// See the [osfmk/mach/port.h][header] header in Apple's kernel sources
///
/// [header]: https://github.com/apple/darwin-xnu/blob/main/osfmk/mach/port.h
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacGuardMachPortFlavor {
    GUARD_EXC_DESTROY = 0x00000001,
    GUARD_EXC_MOD_REFS = 0x00000002,
    GUARD_EXC_SET_CONTEXT = 0x00000004,
    GUARD_EXC_UNGUARDED = 0x00000008,
    GUARD_EXC_INCORRECT_GUARD = 0x00000010,
    GUARD_EXC_IMMOVABLE = 0x00000020,
    GUARD_EXC_STRICT_REPLY = 0x00000040,
    GUARD_EXC_MSG_FILTERED = 0x00000080,
    GUARD_EXC_INVALID_RIGHT = 0x00000100,
    GUARD_EXC_INVALID_NAME = 0x00000200,
    GUARD_EXC_INVALID_VALUE = 0x00000400,
    GUARD_EXC_INVALID_ARGUMENT = 0x00000800,
    GUARD_EXC_RIGHT_EXISTS = 0x00001000,
    GUARD_EXC_KERN_NO_SPACE = 0x00002000,
    GUARD_EXC_KERN_FAILURE = 0x00004000,
    GUARD_EXC_KERN_RESOURCE = 0x00008000,
    GUARD_EXC_SEND_INVALID_REPLY = 0x00010000,
    GUARD_EXC_SEND_INVALID_VOUCHER = 0x00020000,
    GUARD_EXC_SEND_INVALID_RIGHT = 0x00040000,
    GUARD_EXC_RCV_INVALID_NAME = 0x00080000,
    GUARD_EXC_RCV_GUARDED_DESC = 0x00100000,
    GUARD_EXC_MOD_REFS_NON_FATAL = 0x00200000,
    GUARD_EXC_IMMOVABLE_NON_FATAL = 0x00400000,
}

/// Mac/iOS fd guard exception flavors
///
/// See the [bsd/sys/guarded.h][header] header in Apple's kernel sources
///
/// [header]: https://github.com/apple/darwin-xnu/blob/main/bsd/sys/guarded.h
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacGuardFDFlavor {
    GUARD_EXC_CLOSE = 0x00000001,
    GUARD_EXC_DUP = 0x00000002,
    GUARD_EXC_NOCLOEXEC = 0x00000004,
    GUARD_EXC_SOCKET_IPC = 0x00000008,
    GUARD_EXC_FILEPORT = 0x00000010,
    GUARD_EXC_MISMATCH = 0x00000020,
    GUARD_EXC_WRITE = 0x00000040,
}

/// Mac/iOS vnode guard exception flavors
///
/// See the [bsd/sys/guarded.h][header] header in Apple's kernel sources
///
/// [header]: https://github.com/apple/darwin-xnu/blob/main/bsd/sys/guarded.h
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacGuardVNFlavor {
    GUARD_EXC_RENAME_TO = 0x00000001,
    GUARD_EXC_RENAME_FROM = 0x00000002,
    GUARD_EXC_UNLINK = 0x00000004,
    GUARD_EXC_WRITE_OTHER = 0x00000008,
    GUARD_EXC_TRUNC_OTHER = 0x00000010,
    GUARD_EXC_LINK = 0x00000020,
    GUARD_EXC_EXCHDATA = 0x00000040,
}

/// Mac/iOS virtual memory guard exception flavors
///
/// See the [osfmk/mach/vm_statistics.h][header] header in Apple's kernel sources
///
/// [header]: https://github.com/apple/darwin-xnu/blob/main/osfmk/mach/vm_statistics.h
#[derive(Copy, Clone, PartialEq, Debug, Primitive)]
pub enum ExceptionCodeMacGuardVirtMemoryFlavor {
    GUARD_EXC_DEALLOC_GAP = 0x00000001,
}