1 /* Copyright (c) 2006, Google Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 
30 /* minidump_format.h: A cross-platform reimplementation of minidump-related
31  * portions of DbgHelp.h from the Windows Platform SDK.
32  *
33  * (This is C99 source, please don't corrupt it with C++.)
34  *
35  * Structures that are defined by Microsoft to contain a zero-length array
36  * are instead defined here to contain an array with one element, as
37  * zero-length arrays are forbidden by standard C and C++.  In these cases,
38  * *_minsize constants are provided to be used in place of sizeof.  For a
39  * cleaner interface to these sizes when using C++, see minidump_size.h.
40  *
41  * These structures are also sufficient to populate minidump files.
42  *
43  * These definitions may be extended to support handling minidump files
44  * for other CPUs and other operating systems.
45  *
46  * Because precise data type sizes are crucial for this implementation to
47  * function properly and portably in terms of interoperability with minidumps
48  * produced by DbgHelp on Windows, a set of primitive types with known sizes
49  * are used as the basis of each structure defined by this file.  DbgHelp
50  * on Windows is assumed to be the reference implementation; this file
51  * seeks to provide a cross-platform compatible implementation.  To avoid
52  * collisions with the types and values defined and used by DbgHelp in the
53  * event that this implementation is used on Windows, each type and value
54  * defined here is given a new name, beginning with "MD".  Names of the
55  * equivalent types and values in the Windows Platform SDK are given in
56  * comments.
57  *
58  * Author: Mark Mentovai */
59 
60 
61 #ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__
62 #define GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__
63 
64 #include <stddef.h>
65 
66 #include "google_breakpad/common/breakpad_types.h"
67 
68 
69 #if defined(_MSC_VER)
70 /* Disable "zero-sized array in struct/union" warnings when compiling in
71  * MSVC.  DbgHelp.h does this too. */
72 #pragma warning(push)
73 #pragma warning(disable:4200)
74 #endif  /* _MSC_VER */
75 
76 
77 /*
78  * guiddef.h
79  */
80 
81 typedef struct {
82   uint32_t data1;
83   uint16_t data2;
84   uint16_t data3;
85   uint8_t  data4[8];
86 } MDGUID;  /* GUID */
87 
88 
89 /*
90  * WinNT.h
91  */
92 
93 /* Non-x86 CPU identifiers found in the high 24 bits of
94  * (MDRawContext*).context_flags.  These aren't used by Breakpad, but are
95  * defined here for reference, to avoid assigning values that conflict
96  * (although some values already conflict). */
97 #define MD_CONTEXT_IA64  0x00080000  /* CONTEXT_IA64 */
98 /* Additional values from winnt.h in the Windows CE 5.0 SDK: */
99 #define MD_CONTEXT_SHX   0x000000c0  /* CONTEXT_SH4 (Super-H, includes SH3) */
100 #define MD_CONTEXT_ALPHA 0x00020000  /* CONTEXT_ALPHA */
101 
102 /* As of Windows 7 SP1, the number of flag bits has increased to
103  * include 0x40 (CONTEXT_XSTATE):
104  * http://msdn.microsoft.com/en-us/library/hh134238%28v=vs.85%29.aspx */
105 #define MD_CONTEXT_CPU_MASK 0xffffff00
106 
107 
108 /* This is a base type for MDRawContextX86 and MDRawContextPPC.  This
109  * structure should never be allocated directly.  The actual structure type
110  * can be determined by examining the context_flags field. */
111 typedef struct {
112   uint32_t context_flags;
113 } MDRawContextBase;
114 
115 #include "minidump_cpu_amd64.h"
116 #include "minidump_cpu_arm.h"
117 #include "minidump_cpu_arm64.h"
118 #include "minidump_cpu_mips.h"
119 #include "minidump_cpu_ppc.h"
120 #include "minidump_cpu_ppc64.h"
121 #include "minidump_cpu_sparc.h"
122 #include "minidump_cpu_x86.h"
123 
124 /*
125  * WinVer.h
126  */
127 
128 
129 typedef struct {
130   uint32_t signature;
131   uint32_t struct_version;
132   uint32_t file_version_hi;
133   uint32_t file_version_lo;
134   uint32_t product_version_hi;
135   uint32_t product_version_lo;
136   uint32_t file_flags_mask;    /* Identifies valid bits in fileFlags */
137   uint32_t file_flags;
138   uint32_t file_os;
139   uint32_t file_type;
140   uint32_t file_subtype;
141   uint32_t file_date_hi;
142   uint32_t file_date_lo;
143 } MDVSFixedFileInfo;  /* VS_FIXEDFILEINFO */
144 
145 /* For (MDVSFixedFileInfo).signature */
146 #define MD_VSFIXEDFILEINFO_SIGNATURE 0xfeef04bd
147      /* VS_FFI_SIGNATURE */
148 
149 /* For (MDVSFixedFileInfo).version */
150 #define MD_VSFIXEDFILEINFO_VERSION 0x00010000
151      /* VS_FFI_STRUCVERSION */
152 
153 /* For (MDVSFixedFileInfo).file_flags_mask and
154  * (MDVSFixedFileInfo).file_flags */
155 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG        0x00000001
156      /* VS_FF_DEBUG */
157 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRERELEASE   0x00000002
158      /* VS_FF_PRERELEASE */
159 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_PATCHED      0x00000004
160      /* VS_FF_PATCHED */
161 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRIVATEBUILD 0x00000008
162      /* VS_FF_PRIVATEBUILD */
163 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_INFOINFERRED 0x00000010
164      /* VS_FF_INFOINFERRED */
165 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_SPECIALBUILD 0x00000020
166      /* VS_FF_SPECIALBUILD */
167 
168 /* For (MDVSFixedFileInfo).file_os: high 16 bits */
169 #define MD_VSFIXEDFILEINFO_FILE_OS_UNKNOWN    0          /* VOS_UNKNOWN */
170 #define MD_VSFIXEDFILEINFO_FILE_OS_DOS        (1 << 16)  /* VOS_DOS */
171 #define MD_VSFIXEDFILEINFO_FILE_OS_OS216      (2 << 16)  /* VOS_OS216 */
172 #define MD_VSFIXEDFILEINFO_FILE_OS_OS232      (3 << 16)  /* VOS_OS232 */
173 #define MD_VSFIXEDFILEINFO_FILE_OS_NT         (4 << 16)  /* VOS_NT */
174 #define MD_VSFIXEDFILEINFO_FILE_OS_WINCE      (5 << 16)  /* VOS_WINCE */
175 /* Low 16 bits */
176 #define MD_VSFIXEDFILEINFO_FILE_OS__BASE      0          /* VOS__BASE */
177 #define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS16 1          /* VOS__WINDOWS16 */
178 #define MD_VSFIXEDFILEINFO_FILE_OS__PM16      2          /* VOS__PM16 */
179 #define MD_VSFIXEDFILEINFO_FILE_OS__PM32      3          /* VOS__PM32 */
180 #define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32 4          /* VOS__WINDOWS32 */
181 
182 /* For (MDVSFixedFileInfo).file_type */
183 #define MD_VSFIXEDFILEINFO_FILE_TYPE_UNKNOWN    0  /* VFT_UNKNOWN */
184 #define MD_VSFIXEDFILEINFO_FILE_TYPE_APP        1  /* VFT_APP */
185 #define MD_VSFIXEDFILEINFO_FILE_TYPE_DLL        2  /* VFT_DLL */
186 #define MD_VSFIXEDFILEINFO_FILE_TYPE_DRV        3  /* VFT_DLL */
187 #define MD_VSFIXEDFILEINFO_FILE_TYPE_FONT       4  /* VFT_FONT */
188 #define MD_VSFIXEDFILEINFO_FILE_TYPE_VXD        5  /* VFT_VXD */
189 #define MD_VSFIXEDFILEINFO_FILE_TYPE_STATIC_LIB 7  /* VFT_STATIC_LIB */
190 
191 /* For (MDVSFixedFileInfo).file_subtype */
192 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN                0
193      /* VFT2_UNKNOWN */
194 /* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_DRV */
195 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_PRINTER            1
196      /* VFT2_DRV_PRINTER */
197 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_KEYBOARD           2
198      /* VFT2_DRV_KEYBOARD */
199 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_LANGUAGE           3
200      /* VFT2_DRV_LANGUAGE */
201 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_DISPLAY            4
202      /* VFT2_DRV_DISPLAY */
203 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_MOUSE              5
204      /* VFT2_DRV_MOUSE */
205 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_NETWORK            6
206      /* VFT2_DRV_NETWORK */
207 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SYSTEM             7
208      /* VFT2_DRV_SYSTEM */
209 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INSTALLABLE        8
210      /* VFT2_DRV_INSTALLABLE */
211 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SOUND              9
212      /* VFT2_DRV_SOUND */
213 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_COMM              10
214      /* VFT2_DRV_COMM */
215 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INPUTMETHOD       11
216      /* VFT2_DRV_INPUTMETHOD */
217 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_VERSIONED_PRINTER 12
218      /* VFT2_DRV_VERSIONED_PRINTER */
219 /* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_FONT */
220 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_RASTER            1
221      /* VFT2_FONT_RASTER */
222 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_VECTOR            2
223      /* VFT2_FONT_VECTOR */
224 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_TRUETYPE          3
225      /* VFT2_FONT_TRUETYPE */
226 
227 
228 /*
229  * DbgHelp.h
230  */
231 
232 
233 /* An MDRVA is an offset into the minidump file.  The beginning of the
234  * MDRawHeader is at offset 0. */
235 typedef uint32_t MDRVA;   /* RVA   */
236 typedef uint64_t MDRVA64; /* RVA64 */
237 
238 typedef struct {
239   uint32_t  data_size;
240   MDRVA     rva;
241 } MDLocationDescriptor;  /* MINIDUMP_LOCATION_DESCRIPTOR */
242 
243 
244 typedef struct {
245   /* The base address of the memory range on the host that produced the
246    * minidump. */
247   uint64_t             start_of_memory_range;
248 
249   MDLocationDescriptor memory;
250 } MDMemoryDescriptor;  /* MINIDUMP_MEMORY_DESCRIPTOR */
251 
252 
253 typedef struct {
254   uint32_t  signature;
255   uint32_t  version;
256   uint32_t  stream_count;
257   MDRVA     stream_directory_rva;  /* A |stream_count|-sized array of
258                                     * MDRawDirectory structures. */
259   uint32_t  checksum;              /* Can be 0.  In fact, that's all that's
260                                     * been found in minidump files. */
261   uint32_t  time_date_stamp;       /* time_t */
262   uint64_t  flags;
263 } MDRawHeader;  /* MINIDUMP_HEADER */
264 
265 /* For (MDRawHeader).signature and (MDRawHeader).version.  Note that only the
266  * low 16 bits of (MDRawHeader).version are MD_HEADER_VERSION.  Per the
267  * documentation, the high 16 bits are implementation-specific. */
268 #define MD_HEADER_SIGNATURE 0x504d444d /* 'PMDM' */
269      /* MINIDUMP_SIGNATURE */
270 #define MD_HEADER_VERSION   0x0000a793 /* 42899 */
271      /* MINIDUMP_VERSION */
272 
273 /* For (MDRawHeader).flags: */
274 typedef enum {
275   /* MD_NORMAL is the standard type of minidump.  It includes full
276    * streams for the thread list, module list, exception, system info,
277    * and miscellaneous info.  A memory list stream is also present,
278    * pointing to the same stack memory contained in the thread list,
279    * as well as a 256-byte region around the instruction address that
280    * was executing when the exception occurred.  Stack memory is from
281    * 4 bytes below a thread's stack pointer up to the top of the
282    * memory region encompassing the stack. */
283   MD_NORMAL                            = 0x00000000,
284   MD_WITH_DATA_SEGS                    = 0x00000001,
285   MD_WITH_FULL_MEMORY                  = 0x00000002,
286   MD_WITH_HANDLE_DATA                  = 0x00000004,
287   MD_FILTER_MEMORY                     = 0x00000008,
288   MD_SCAN_MEMORY                       = 0x00000010,
289   MD_WITH_UNLOADED_MODULES             = 0x00000020,
290   MD_WITH_INDIRECTLY_REFERENCED_MEMORY = 0x00000040,
291   MD_FILTER_MODULE_PATHS               = 0x00000080,
292   MD_WITH_PROCESS_THREAD_DATA          = 0x00000100,
293   MD_WITH_PRIVATE_READ_WRITE_MEMORY    = 0x00000200,
294   MD_WITHOUT_OPTIONAL_DATA             = 0x00000400,
295   MD_WITH_FULL_MEMORY_INFO             = 0x00000800,
296   MD_WITH_THREAD_INFO                  = 0x00001000,
297   MD_WITH_CODE_SEGS                    = 0x00002000,
298   MD_WITHOUT_AUXILLIARY_SEGS           = 0x00004000,
299   MD_WITH_FULL_AUXILLIARY_STATE        = 0x00008000,
300   MD_WITH_PRIVATE_WRITE_COPY_MEMORY    = 0x00010000,
301   MD_IGNORE_INACCESSIBLE_MEMORY        = 0x00020000,
302   MD_WITH_TOKEN_INFORMATION            = 0x00040000
303 } MDType;  /* MINIDUMP_TYPE */
304 
305 
306 typedef struct {
307   uint32_t             stream_type;
308   MDLocationDescriptor location;
309 } MDRawDirectory;  /* MINIDUMP_DIRECTORY */
310 
311 /* For (MDRawDirectory).stream_type */
312 typedef enum {
313   MD_UNUSED_STREAM               =  0,
314   MD_RESERVED_STREAM_0           =  1,
315   MD_RESERVED_STREAM_1           =  2,
316   MD_THREAD_LIST_STREAM          =  3,  /* MDRawThreadList */
317   MD_MODULE_LIST_STREAM          =  4,  /* MDRawModuleList */
318   MD_MEMORY_LIST_STREAM          =  5,  /* MDRawMemoryList */
319   MD_EXCEPTION_STREAM            =  6,  /* MDRawExceptionStream */
320   MD_SYSTEM_INFO_STREAM          =  7,  /* MDRawSystemInfo */
321   MD_THREAD_EX_LIST_STREAM       =  8,
322   MD_MEMORY_64_LIST_STREAM       =  9,
323   MD_COMMENT_STREAM_A            = 10,
324   MD_COMMENT_STREAM_W            = 11,
325   MD_HANDLE_DATA_STREAM          = 12,
326   MD_FUNCTION_TABLE_STREAM       = 13,
327   MD_UNLOADED_MODULE_LIST_STREAM = 14,
328   MD_MISC_INFO_STREAM            = 15,  /* MDRawMiscInfo */
329   MD_MEMORY_INFO_LIST_STREAM     = 16,  /* MDRawMemoryInfoList */
330   MD_THREAD_INFO_LIST_STREAM     = 17,
331   MD_HANDLE_OPERATION_LIST_STREAM = 18,
332   MD_TOKEN_STREAM                = 19,
333   MD_JAVASCRIPT_DATA_STREAM      = 20,
334   MD_SYSTEM_MEMORY_INFO_STREAM   = 21,
335   MD_PROCESS_VM_COUNTERS_STREAM  = 22,
336   MD_IPT_TRACE_STREAM            = 23,
337   MD_THREAD_NAMES_STREAM         = 24,
338   MD_LAST_RESERVED_STREAM        = 0x0000ffff,
339 
340   /* Breakpad extension types.  0x4767 = "Gg" */
341   MD_BREAKPAD_INFO_STREAM        = 0x47670001,  /* MDRawBreakpadInfo  */
342   MD_ASSERTION_INFO_STREAM       = 0x47670002,  /* MDRawAssertionInfo */
343   /* These are additional minidump stream values which are specific to
344    * the linux breakpad implementation. */
345   MD_LINUX_CPU_INFO              = 0x47670003,  /* /proc/cpuinfo      */
346   MD_LINUX_PROC_STATUS           = 0x47670004,  /* /proc/$x/status    */
347   MD_LINUX_LSB_RELEASE           = 0x47670005,  /* /etc/lsb-release   */
348   MD_LINUX_CMD_LINE              = 0x47670006,  /* /proc/$x/cmdline   */
349   MD_LINUX_ENVIRON               = 0x47670007,  /* /proc/$x/environ   */
350   MD_LINUX_AUXV                  = 0x47670008,  /* /proc/$x/auxv      */
351   MD_LINUX_MAPS                  = 0x47670009,  /* /proc/$x/maps      */
352   MD_LINUX_DSO_DEBUG             = 0x4767000A,  /* MDRawDebug{32,64}  */
353 
354   /* Crashpad extension types. 0x4350 = "CP"
355    * See Crashpad's minidump/minidump_extensions.h. */
356   MD_CRASHPAD_INFO_STREAM        = 0x43500001,  /* MDRawCrashpadInfo  */
357 
358   /* Data from the __DATA,__crash_info section of every module which contains
359    * one that has useful data. Only available on macOS. 0x4D7A = "Mz". */
360   MOZ_MACOS_CRASH_INFO_STREAM    = 0x4d7a0001,
361 } MDStreamType;  /* MINIDUMP_STREAM_TYPE */
362 
363 
364 typedef struct {
365   uint32_t length;     /* Length of buffer in bytes (not characters),
366                         * excluding 0-terminator */
367   uint16_t buffer[1];  /* UTF-16-encoded, 0-terminated */
368 } MDString;  /* MINIDUMP_STRING */
369 
370 static const size_t MDString_minsize = offsetof(MDString, buffer[0]);
371 
372 
373 typedef struct {
374   uint32_t             thread_id;
375   uint32_t             suspend_count;
376   uint32_t             priority_class;
377   uint32_t             priority;
378   uint64_t             teb;             /* Thread environment block */
379   MDMemoryDescriptor   stack;
380   MDLocationDescriptor thread_context;  /* MDRawContext[CPU] */
381 } MDRawThread;  /* MINIDUMP_THREAD */
382 
383 
384 typedef struct {
385   uint32_t    number_of_threads;
386   MDRawThread threads[1];
387 } MDRawThreadList;  /* MINIDUMP_THREAD_LIST */
388 
389 static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList,
390                                                        threads[0]);
391 
392 
393 typedef struct {
394   uint64_t             base_of_image;
395   uint32_t             size_of_image;
396   uint32_t             checksum;         /* 0 if unknown */
397   uint32_t             time_date_stamp;  /* time_t */
398   MDRVA                module_name_rva;  /* MDString, pathname or filename */
399   MDVSFixedFileInfo    version_info;
400 
401   /* The next field stores a CodeView record and is populated when a module's
402    * debug information resides in a PDB file.  It identifies the PDB file. */
403   MDLocationDescriptor cv_record;
404 
405   /* The next field is populated when a module's debug information resides
406    * in a DBG file.  It identifies the DBG file.  This field is effectively
407    * obsolete with modules built by recent toolchains. */
408   MDLocationDescriptor misc_record;
409 
410   /* Alignment problem: reserved0 and reserved1 are defined by the platform
411    * SDK as 64-bit quantities.  However, that results in a structure whose
412    * alignment is unpredictable on different CPUs and ABIs.  If the ABI
413    * specifies full alignment of 64-bit quantities in structures (as ppc
414    * does), there will be padding between miscRecord and reserved0.  If
415    * 64-bit quantities can be aligned on 32-bit boundaries (as on x86),
416    * this padding will not exist.  (Note that the structure up to this point
417    * contains 1 64-bit member followed by 21 32-bit members.)
418    * As a workaround, reserved0 and reserved1 are instead defined here as
419    * four 32-bit quantities.  This should be harmless, as there are
420    * currently no known uses for these fields. */
421   uint32_t             reserved0[2];
422   uint32_t             reserved1[2];
423 } MDRawModule;  /* MINIDUMP_MODULE */
424 
425 /* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to
426  * be tail-padded out to a multiple of 64 bits under some ABIs (such as PPC).
427  * This doesn't occur on systems that don't tail-pad in this manner.  Define
428  * this macro to be the usable size of the MDRawModule struct, and use it in
429  * place of sizeof(MDRawModule). */
430 #define MD_MODULE_SIZE 108
431 
432 
433 /* (MDRawModule).cv_record can reference MDCVInfoPDB20 or MDCVInfoPDB70.
434  * Ref.: http://www.debuginfo.com/articles/debuginfomatch.html
435  * MDCVInfoPDB70 is the expected structure type with recent toolchains. */
436 
437 typedef struct {
438   uint32_t signature;
439   uint32_t offset;     /* Offset to debug data (expect 0 in minidump) */
440 } MDCVHeader;
441 
442 typedef struct {
443   MDCVHeader cv_header;
444   uint32_t   signature;         /* time_t debug information created */
445   uint32_t   age;               /* revision of PDB file */
446   uint8_t    pdb_file_name[1];  /* Pathname or filename of PDB file */
447 } MDCVInfoPDB20;
448 
449 static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20,
450                                                      pdb_file_name[0]);
451 
452 #define MD_CVINFOPDB20_SIGNATURE 0x3031424e  /* cvHeader.signature = '01BN' */
453 
454 typedef struct {
455   uint32_t  cv_signature;
456   MDGUID    signature;         /* GUID, identifies PDB file */
457   uint32_t  age;               /* Identifies incremental changes to PDB file */
458   uint8_t   pdb_file_name[1];  /* Pathname or filename of PDB file,
459                                 * 0-terminated 8-bit character data (UTF-8?) */
460 } MDCVInfoPDB70;
461 
462 static const size_t MDCVInfoPDB70_minsize = offsetof(MDCVInfoPDB70,
463                                                      pdb_file_name[0]);
464 
465 #define MD_CVINFOPDB70_SIGNATURE 0x53445352  /* cvSignature = 'SDSR' */
466 
467 /*
468  * Modern ELF toolchains insert a "build id" into the ELF headers that
469  * usually contains a hash of some ELF headers + sections to uniquely
470  * identify a binary.
471  *
472  * https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Developer_Guide/compiling-build-id.html
473  * https://sourceware.org/binutils/docs-2.26/ld/Options.html#index-g_t_002d_002dbuild_002did-292
474  */
475 typedef struct {
476   uint32_t cv_signature;
477   uint8_t  build_id[1];  /* Bytes of build id from GNU_BUILD_ID ELF note.
478                           * This is variable-length, but usually 20 bytes
479                           * as the binutils ld default is a SHA-1 hash. */
480 } MDCVInfoELF;
481 
482 static const size_t MDCVInfoELF_minsize = offsetof(MDCVInfoELF,
483                                                    build_id[0]);
484 
485 #define MD_CVINFOELF_SIGNATURE 0x4270454c  /* cvSignature = 'BpEL' */
486 
487 /* In addition to the two CodeView record formats above, used for linking
488  * to external pdb files, it is possible for debugging data to be carried
489  * directly in the CodeView record itself.  These signature values will
490  * be found in the first 4 bytes of the CodeView record.  Additional values
491  * not commonly experienced in the wild are given by "Microsoft Symbol and
492  * Type Information", http://www.x86.org/ftp/manuals/tools/sym.pdf, section
493  * 7.2.  An in-depth description of the CodeView 4.1 format is given by
494  * "Undocumented Windows 2000 Secrets", Windows 2000 Debugging Support/
495  * Microsoft Symbol File Internals/CodeView Subsections,
496  * http://www.rawol.com/features/undocumented/sbs-w2k-1-windows-2000-debugging-support.pdf
497  */
498 #define MD_CVINFOCV41_SIGNATURE 0x3930424e  /* '90BN', CodeView 4.10. */
499 #define MD_CVINFOCV50_SIGNATURE 0x3131424e  /* '11BN', CodeView 5.0,
500                                              * MS C7-format (/Z7). */
501 
502 #define MD_CVINFOUNKNOWN_SIGNATURE 0xffffffff  /* An unlikely value. */
503 
504 /* (MDRawModule).miscRecord can reference MDImageDebugMisc.  The Windows
505  * structure is actually defined in WinNT.h.  This structure is effectively
506  * obsolete with modules built by recent toolchains. */
507 
508 typedef struct {
509   uint32_t  data_type;    /* IMAGE_DEBUG_TYPE_*, not defined here because
510                            * this debug record type is mostly obsolete. */
511   uint32_t  length;       /* Length of entire MDImageDebugMisc structure */
512   uint8_t   unicode;      /* True if data is multibyte */
513   uint8_t   reserved[3];
514   uint8_t   data[1];
515 } MDImageDebugMisc;  /* IMAGE_DEBUG_MISC */
516 
517 static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc,
518                                                         data[0]);
519 
520 
521 typedef struct {
522   uint32_t    number_of_modules;
523   MDRawModule modules[1];
524 } MDRawModuleList;  /* MINIDUMP_MODULE_LIST */
525 
526 static const size_t MDRawModuleList_minsize = offsetof(MDRawModuleList,
527                                                        modules[0]);
528 
529 
530 typedef struct {
531   uint32_t           number_of_memory_ranges;
532   MDMemoryDescriptor memory_ranges[1];
533 } MDRawMemoryList;  /* MINIDUMP_MEMORY_LIST */
534 
535 static const size_t MDRawMemoryList_minsize = offsetof(MDRawMemoryList,
536                                                        memory_ranges[0]);
537 
538 
539 #define MD_EXCEPTION_MAXIMUM_PARAMETERS 15
540 
541 typedef struct {
542   uint32_t  exception_code;     /* Windows: MDExceptionCodeWin,
543                                  * Mac OS X: MDExceptionMac,
544                                  * Linux: MDExceptionCodeLinux. */
545   uint32_t  exception_flags;    /* Windows: 1 if noncontinuable,
546                                    Mac OS X: MDExceptionCodeMac. */
547   uint64_t  exception_record;   /* Address (in the minidump-producing host's
548                                  * memory) of another MDException, for
549                                  * nested exceptions. */
550   uint64_t  exception_address;  /* The address that caused the exception.
551                                  * Mac OS X: exception subcode (which is
552                                  *           typically the address). */
553   uint32_t  number_parameters;  /* Number of valid elements in
554                                  * exception_information. */
555   uint32_t  __align;
556   uint64_t  exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS];
557 } MDException;  /* MINIDUMP_EXCEPTION */
558 
559 #include "minidump_exception_fuchsia.h"
560 #include "minidump_exception_linux.h"
561 #include "minidump_exception_mac.h"
562 #include "minidump_exception_ps3.h"
563 #include "minidump_exception_solaris.h"
564 #include "minidump_exception_win32.h"
565 
566 typedef struct {
567   uint32_t             thread_id;         /* Thread in which the exception
568                                            * occurred.  Corresponds to
569                                            * (MDRawThread).thread_id. */
570   uint32_t             __align;
571   MDException          exception_record;
572   MDLocationDescriptor thread_context;    /* MDRawContext[CPU] */
573 } MDRawExceptionStream;  /* MINIDUMP_EXCEPTION_STREAM */
574 
575 
576 typedef union {
577   struct {
578     uint32_t vendor_id[3];               /* cpuid 0: ebx, edx, ecx */
579     uint32_t version_information;        /* cpuid 1: eax */
580     uint32_t feature_information;        /* cpuid 1: edx */
581     uint32_t amd_extended_cpu_features;  /* cpuid 0x80000001, ebx */
582   } x86_cpu_info;
583   struct {
584     uint32_t cpuid;
585     uint32_t elf_hwcaps;    /* linux specific, 0 otherwise */
586   } arm_cpu_info;
587   struct {
588     uint64_t processor_features[2];
589   } other_cpu_info;
590 } MDCPUInformation;  /* CPU_INFORMATION */
591 
592 /* For (MDCPUInformation).arm_cpu_info.elf_hwcaps.
593  * This matches the Linux kernel definitions from <asm/hwcaps.h> */
594 typedef enum {
595   MD_CPU_ARM_ELF_HWCAP_SWP       = (1 << 0),
596   MD_CPU_ARM_ELF_HWCAP_HALF      = (1 << 1),
597   MD_CPU_ARM_ELF_HWCAP_THUMB     = (1 << 2),
598   MD_CPU_ARM_ELF_HWCAP_26BIT     = (1 << 3),
599   MD_CPU_ARM_ELF_HWCAP_FAST_MULT = (1 << 4),
600   MD_CPU_ARM_ELF_HWCAP_FPA       = (1 << 5),
601   MD_CPU_ARM_ELF_HWCAP_VFP       = (1 << 6),
602   MD_CPU_ARM_ELF_HWCAP_EDSP      = (1 << 7),
603   MD_CPU_ARM_ELF_HWCAP_JAVA      = (1 << 8),
604   MD_CPU_ARM_ELF_HWCAP_IWMMXT    = (1 << 9),
605   MD_CPU_ARM_ELF_HWCAP_CRUNCH    = (1 << 10),
606   MD_CPU_ARM_ELF_HWCAP_THUMBEE   = (1 << 11),
607   MD_CPU_ARM_ELF_HWCAP_NEON      = (1 << 12),
608   MD_CPU_ARM_ELF_HWCAP_VFPv3     = (1 << 13),
609   MD_CPU_ARM_ELF_HWCAP_VFPv3D16  = (1 << 14),
610   MD_CPU_ARM_ELF_HWCAP_TLS       = (1 << 15),
611   MD_CPU_ARM_ELF_HWCAP_VFPv4     = (1 << 16),
612   MD_CPU_ARM_ELF_HWCAP_IDIVA     = (1 << 17),
613   MD_CPU_ARM_ELF_HWCAP_IDIVT     = (1 << 18),
614 } MDCPUInformationARMElfHwCaps;
615 
616 typedef struct {
617   /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO
618    * structure as returned by GetSystemInfo */
619   uint16_t         processor_architecture;
620   uint16_t         processor_level;         /* x86: 5 = 586, 6 = 686, ... */
621                                             /* ARM: 6 = ARMv6, 7 = ARMv7 ... */
622   uint16_t         processor_revision;      /* x86: 0xMMSS, where MM=model,
623                                              *      SS=stepping */
624                                             /* ARM: 0 */
625 
626   uint8_t          number_of_processors;
627   uint8_t          product_type;            /* Windows: VER_NT_* from WinNT.h */
628 
629   /* The next 5 fields are from the OSVERSIONINFO structure as returned
630    * by GetVersionEx */
631   uint32_t         major_version;
632   uint32_t         minor_version;
633   uint32_t         build_number;
634   uint32_t         platform_id;
635   MDRVA            csd_version_rva;  /* MDString further identifying the
636                                       * host OS.
637                                       * Windows: name of the installed OS
638                                       *          service pack.
639                                       * Mac OS X: the Apple OS build number
640                                       *           (sw_vers -buildVersion).
641                                       * Linux: uname -srvmo */
642 
643   uint16_t         suite_mask;       /* Windows: VER_SUITE_* from WinNT.h */
644   uint16_t         reserved2;
645 
646   MDCPUInformation cpu;
647 } MDRawSystemInfo;  /* MINIDUMP_SYSTEM_INFO */
648 
649 /* For (MDRawSystemInfo).processor_architecture: */
650 typedef enum {
651   MD_CPU_ARCHITECTURE_X86       =  0,  /* PROCESSOR_ARCHITECTURE_INTEL */
652   MD_CPU_ARCHITECTURE_MIPS      =  1,  /* PROCESSOR_ARCHITECTURE_MIPS */
653   MD_CPU_ARCHITECTURE_ALPHA     =  2,  /* PROCESSOR_ARCHITECTURE_ALPHA */
654   MD_CPU_ARCHITECTURE_PPC       =  3,  /* PROCESSOR_ARCHITECTURE_PPC */
655   MD_CPU_ARCHITECTURE_SHX       =  4,  /* PROCESSOR_ARCHITECTURE_SHX
656                                         * (Super-H) */
657   MD_CPU_ARCHITECTURE_ARM       =  5,  /* PROCESSOR_ARCHITECTURE_ARM */
658   MD_CPU_ARCHITECTURE_IA64      =  6,  /* PROCESSOR_ARCHITECTURE_IA64 */
659   MD_CPU_ARCHITECTURE_ALPHA64   =  7,  /* PROCESSOR_ARCHITECTURE_ALPHA64 */
660   MD_CPU_ARCHITECTURE_MSIL      =  8,  /* PROCESSOR_ARCHITECTURE_MSIL
661                                         * (Microsoft Intermediate Language) */
662   MD_CPU_ARCHITECTURE_AMD64     =  9,  /* PROCESSOR_ARCHITECTURE_AMD64 */
663   MD_CPU_ARCHITECTURE_X86_WIN64 = 10,
664       /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
665   MD_CPU_ARCHITECTURE_ARM64     = 12,  /* PROCESSOR_ARCHITECTURE_ARM64 */
666   MD_CPU_ARCHITECTURE_SPARC     = 0x8001, /* Breakpad-defined value for SPARC */
667   MD_CPU_ARCHITECTURE_PPC64     = 0x8002, /* Breakpad-defined value for PPC64 */
668   MD_CPU_ARCHITECTURE_ARM64_OLD = 0x8003, /* Breakpad-defined value for ARM64 */
669   MD_CPU_ARCHITECTURE_MIPS64    = 0x8004, /* Breakpad-defined value for MIPS64 */
670   MD_CPU_ARCHITECTURE_UNKNOWN   = 0xffff  /* PROCESSOR_ARCHITECTURE_UNKNOWN */
671 } MDCPUArchitecture;
672 
673 /* For (MDRawSystemInfo).platform_id: */
674 typedef enum {
675   MD_OS_WIN32S        = 0,  /* VER_PLATFORM_WIN32s (Windows 3.1) */
676   MD_OS_WIN32_WINDOWS = 1,  /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
677   MD_OS_WIN32_NT      = 2,  /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
678   MD_OS_WIN32_CE      = 3,  /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
679                              * (Windows CE, Windows Mobile, "Handheld") */
680 
681   /* The following values are Breakpad-defined. */
682   MD_OS_UNIX          = 0x8000,  /* Generic Unix-ish */
683   MD_OS_MAC_OS_X      = 0x8101,  /* Mac OS X/Darwin */
684   MD_OS_IOS           = 0x8102,  /* iOS */
685   MD_OS_LINUX         = 0x8201,  /* Linux */
686   MD_OS_SOLARIS       = 0x8202,  /* Solaris */
687   MD_OS_ANDROID       = 0x8203,  /* Android */
688   MD_OS_PS3           = 0x8204,  /* PS3 */
689   MD_OS_NACL          = 0x8205,  /* Native Client (NaCl) */
690   MD_OS_FUCHSIA       = 0x8206   /* Fuchsia */
691 } MDOSPlatform;
692 
693 typedef struct {
694   uint64_t base_of_image;
695   uint32_t size_of_image;
696   uint32_t checksum;
697   uint32_t time_date_stamp;
698   MDRVA module_name_rva;
699 } MDRawUnloadedModule;
700 
701 typedef struct {
702   uint32_t size_of_header;
703   uint32_t size_of_entry;
704   uint32_t number_of_entries;
705 } MDRawUnloadedModuleList;  /* MINIDUMP_UNLOADED_MODULE_LIST */
706 
707 typedef struct {
708   uint16_t year;
709   uint16_t month;
710   uint16_t day_of_week;
711   uint16_t day;
712   uint16_t hour;
713   uint16_t minute;
714   uint16_t second;
715   uint16_t milliseconds;
716 } MDSystemTime;  /* SYSTEMTIME */
717 
718 typedef struct {
719   /* Required field.  The bias is the difference, in minutes, between
720    * Coordinated Universal Time (UTC) and local time.
721    *   Formula: UTC = local time + bias */
722   int32_t bias;
723   /* A description for standard time.  For example, "EST" could indicate Eastern
724    * Standard Time.  In practice this contains the full time zone names.  This
725    * string can be empty. */
726   uint16_t standard_name[32];  /* UTF-16-encoded, 0-terminated */
727   /* A MDSystemTime structure that contains a date and local time when the
728    * transition from daylight saving time to standard time occurs on this
729    * operating system.  If the time zone does not support daylight saving time,
730    * the month member in the MDSystemTime structure is zero. */
731   MDSystemTime standard_date;
732   /* The bias value to be used during local time translations that occur during
733    * standard time. */
734   int32_t standard_bias;
735   /* A description for daylight saving time.  For example, "PDT" could indicate
736    * Pacific Daylight Time.  In practice this contains the full time zone names.
737    * This string can be empty. */
738   uint16_t daylight_name[32];  /* UTF-16-encoded, 0-terminated */
739   /* A MDSystemTime structure that contains a date and local time when the
740    * transition from standard time to daylight saving time occurs on this
741    * operating system.  If the time zone does not support daylight saving time,
742    * the month member in the MDSystemTime structure is zero.*/
743   MDSystemTime daylight_date;
744   /* The bias value to be used during local time translations that occur during
745    * daylight saving time. */
746   int32_t daylight_bias;
747 } MDTimeZoneInformation;  /* TIME_ZONE_INFORMATION */
748 
749 /* MAX_PATH from windef.h */
750 #define MD_MAX_PATH 260
751 
752 /* For MDXStateConfigFeatureMscInfo.features */
753 typedef struct {
754   uint32_t offset;
755   uint32_t size;
756 } MDXStateFeature;
757 
758 /* For MDXStateConfigFeatureMscInfo.enabled_features from winnt.h */
759 typedef enum {
760   MD_XSTATE_LEGACY_FLOATING_POINT = 0, /* XSTATE_LEGACY_FLOATING_POINT */
761   MD_XSTATE_LEGACY_SSE            = 1, /* XSTATE_LEGACY_SSE */
762   MD_XSTATE_GSSE                  = 2, /* XSTATE_GSSE */
763   MD_XSTATE_AVX                   = MD_XSTATE_GSSE, /* XSTATE_AVX */
764   MD_XSTATE_MPX_BNDREGS           = 3, /* XSTATE_MPX_BNDREGS */
765   MD_XSTATE_MPX_BNDCSR            = 4, /* XSTATE_MPX_BNDCSR */
766   MD_XSTATE_AVX512_KMASK          = 5, /* XSTATE_AVX512_KMASK */
767   MD_XSTATE_AVX512_ZMM_H          = 6, /* XSTATE_AVX512_ZMM_H */
768   MD_XSTATE_AVX512_ZMM            = 7, /* XSTATE_AVX512_ZMM */
769   MD_XSTATE_IPT                   = 8, /* XSTATE_IPT */
770   MD_XSTATE_LWP                   = 62 /* XSTATE_LWP */
771 } MDXStateFeatureFlag;
772 
773 /* MAXIMUM_XSTATE_FEATURES from winnt.h */
774 #define MD_MAXIMUM_XSTATE_FEATURES 64
775 
776 /* For MDRawMiscInfo.xstate_data */
777 typedef struct {
778   uint32_t size_of_info;
779   uint32_t context_size;
780   /* An entry in the features array is valid only if the corresponding bit in
781    * the enabled_features flag is set. */
782   uint64_t enabled_features;
783   MDXStateFeature features[MD_MAXIMUM_XSTATE_FEATURES];
784 } MDXStateConfigFeatureMscInfo;
785 
786 
787 /* The miscellaneous information stream contains a variety
788  * of small pieces of information.  A member is valid if
789  * it's within the available size and its corresponding
790  * bit is set. */
791 typedef struct {
792   uint32_t size_of_info;  /* Length of entire MDRawMiscInfo structure. */
793   uint32_t flags1;
794 
795   /* The next field is only valid if flags1 contains
796    * MD_MISCINFO_FLAGS1_PROCESS_ID. */
797   uint32_t process_id;
798 
799   /* The next 3 fields are only valid if flags1 contains
800    * MD_MISCINFO_FLAGS1_PROCESS_TIMES. */
801   uint32_t process_create_time;  /* time_t process started */
802   uint32_t process_user_time;    /* seconds of user CPU time */
803   uint32_t process_kernel_time;  /* seconds of kernel CPU time */
804 
805   /* The following fields are not present in MINIDUMP_MISC_INFO but are
806    * in MINIDUMP_MISC_INFO_2.  When this struct is populated, these values
807    * may not be set.  Use flags1 and size_of_info to determine whether these
808    * values are present.  These are only valid when flags1 contains
809    * MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
810   uint32_t processor_max_mhz;
811   uint32_t processor_current_mhz;
812   uint32_t processor_mhz_limit;
813   uint32_t processor_max_idle_state;
814   uint32_t processor_current_idle_state;
815 
816   /* The following fields are not present in MINIDUMP_MISC_INFO_2 but are
817    * in MINIDUMP_MISC_INFO_3.  When this struct is populated, these values
818    * may not be set.  Use flags1 and size_of_info to determine whether these
819    * values are present. */
820 
821   /* The following field is only valid if flags1 contains
822    * MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY. */
823   uint32_t process_integrity_level;
824 
825   /* The following field is only valid if flags1 contains
826    * MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS. */
827   uint32_t process_execute_flags;
828 
829   /* The following field is only valid if flags1 contains
830    * MD_MISCINFO_FLAGS1_PROTECTED_PROCESS. */
831   uint32_t protected_process;
832 
833   /* The following 2 fields are only valid if flags1 contains
834    * MD_MISCINFO_FLAGS1_TIMEZONE. */
835   uint32_t time_zone_id;
836   MDTimeZoneInformation time_zone;
837 
838   /* The following fields are not present in MINIDUMP_MISC_INFO_3 but are
839    * in MINIDUMP_MISC_INFO_4.  When this struct is populated, these values
840    * may not be set.  Use flags1 and size_of_info to determine whether these
841    * values are present. */
842 
843   /* The following 2 fields are only valid if flags1 contains
844    * MD_MISCINFO_FLAGS1_BUILDSTRING. */
845   uint16_t build_string[MD_MAX_PATH];  /* UTF-16-encoded, 0-terminated */
846   uint16_t dbg_bld_str[40];            /* UTF-16-encoded, 0-terminated */
847 
848   /* The following fields are not present in MINIDUMP_MISC_INFO_4 but are
849    * in MINIDUMP_MISC_INFO_5.  When this struct is populated, these values
850    * may not be set.  Use flags1 and size_of_info to determine whether these
851    * values are present. */
852 
853   /* The following field has its own flags for establishing the validity of
854    * the structure's contents.*/
855   MDXStateConfigFeatureMscInfo xstate_data;
856 
857   /* The following field is only valid if flags1 contains
858    * MD_MISCINFO_FLAGS1_PROCESS_COOKIE. */
859   uint32_t process_cookie;
860 } MDRawMiscInfo;  /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
861                    * MINIDUMP_MISC_INFO_3, MINIDUMP_MISC_INFO_4,
862                    * MINIDUMP_MISC_INFO_5, MINIDUMP_MISC_INFO_N */
863 
864 static const size_t MD_MISCINFO_SIZE =
865     offsetof(MDRawMiscInfo, processor_max_mhz);
866 static const size_t MD_MISCINFO2_SIZE =
867     offsetof(MDRawMiscInfo, process_integrity_level);
868 static const size_t MD_MISCINFO3_SIZE =
869     offsetof(MDRawMiscInfo, build_string[0]);
870 static const size_t MD_MISCINFO4_SIZE =
871     offsetof(MDRawMiscInfo, xstate_data);
872 /* Version 5 of the MDRawMiscInfo structure is not a multiple of 8 in size and
873  * yet it contains some 8-bytes sized fields. This causes many compilers to
874  * round the structure size up to a multiple of 8 by adding padding at the end.
875  * The following hack is thus required for matching the proper on-disk size. */
876 static const size_t MD_MISCINFO5_SIZE =
877     offsetof(MDRawMiscInfo, process_cookie) + sizeof(uint32_t);
878 
879 /* For (MDRawMiscInfo).flags1.  These values indicate which fields in the
880  * MDRawMiscInfoStructure are valid. */
881 typedef enum {
882   MD_MISCINFO_FLAGS1_PROCESS_ID            = 0x00000001,
883       /* MINIDUMP_MISC1_PROCESS_ID */
884   MD_MISCINFO_FLAGS1_PROCESS_TIMES         = 0x00000002,
885       /* MINIDUMP_MISC1_PROCESS_TIMES */
886   MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO  = 0x00000004,
887       /* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
888   MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY     = 0x00000010,
889       /* MINIDUMP_MISC3_PROCESS_INTEGRITY */
890   MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS = 0x00000020,
891       /* MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS */
892   MD_MISCINFO_FLAGS1_TIMEZONE              = 0x00000040,
893       /* MINIDUMP_MISC3_TIMEZONE */
894   MD_MISCINFO_FLAGS1_PROTECTED_PROCESS     = 0x00000080,
895       /* MINIDUMP_MISC3_PROTECTED_PROCESS */
896   MD_MISCINFO_FLAGS1_BUILDSTRING           = 0x00000100,
897       /* MINIDUMP_MISC4_BUILDSTRING */
898   MD_MISCINFO_FLAGS1_PROCESS_COOKIE        = 0x00000200,
899       /* MINIDUMP_MISC5_PROCESS_COOKIE */
900 } MDMiscInfoFlags1;
901 
902 /*
903  * Around DbgHelp version 6.0, the style of new LIST structures changed
904  * from including an array of length 1 at the end of the struct to
905  * represent the variable-length data to including explicit
906  * "size of header", "size of entry" and "number of entries" fields
907  * in the header, presumably to allow backwards-compatibly-extending
908  * the structures in the future. The actual list entries follow the
909  * header data directly in this case.
910  */
911 
912 typedef struct {
913   uint32_t size_of_header;    /* sizeof(MDRawMemoryInfoList) */
914   uint32_t size_of_entry;     /* sizeof(MDRawMemoryInfo) */
915   uint64_t number_of_entries;
916 } MDRawMemoryInfoList;  /* MINIDUMP_MEMORY_INFO_LIST */
917 
918 typedef struct {
919   uint64_t  base_address;           /* Base address of a region of pages */
920   uint64_t  allocation_base;        /* Base address of a range of pages
921                                      * within this region. */
922   uint32_t  allocation_protection;  /* Memory protection when this region
923                                      * was originally allocated:
924                                      * MDMemoryProtection */
925   uint32_t  __alignment1;
926   uint64_t  region_size;
927   uint32_t  state;                  /* MDMemoryState */
928   uint32_t  protection;             /* MDMemoryProtection */
929   uint32_t  type;                   /* MDMemoryType */
930   uint32_t  __alignment2;
931 } MDRawMemoryInfo;  /* MINIDUMP_MEMORY_INFO */
932 
933 /* For (MDRawMemoryInfo).state */
934 typedef enum {
935   MD_MEMORY_STATE_COMMIT   = 0x1000,  /* physical storage has been allocated */
936   MD_MEMORY_STATE_RESERVE  = 0x2000,  /* reserved, but no physical storage */
937   MD_MEMORY_STATE_FREE     = 0x10000  /* available to be allocated */
938 } MDMemoryState;
939 
940 /* For (MDRawMemoryInfo).allocation_protection and .protection */
941 typedef enum {
942   MD_MEMORY_PROTECT_NOACCESS          = 0x01,  /* PAGE_NOACCESS */
943   MD_MEMORY_PROTECT_READONLY          = 0x02,  /* PAGE_READONLY */
944   MD_MEMORY_PROTECT_READWRITE         = 0x04,  /* PAGE_READWRITE */
945   MD_MEMORY_PROTECT_WRITECOPY         = 0x08,  /* PAGE_WRITECOPY */
946   MD_MEMORY_PROTECT_EXECUTE           = 0x10,  /* PAGE_EXECUTE */
947   MD_MEMORY_PROTECT_EXECUTE_READ      = 0x20,  /* PAGE_EXECUTE_READ */
948   MD_MEMORY_PROTECT_EXECUTE_READWRITE = 0x40,  /* PAGE_EXECUTE_READWRITE */
949   MD_MEMORY_PROTECT_EXECUTE_WRITECOPY = 0x80,  /* PAGE_EXECUTE_WRITECOPY */
950   /* These options can be combined with the previous flags. */
951   MD_MEMORY_PROTECT_GUARD             = 0x100,  /* PAGE_GUARD */
952   MD_MEMORY_PROTECT_NOCACHE           = 0x200,  /* PAGE_NOCACHE */
953   MD_MEMORY_PROTECT_WRITECOMBINE      = 0x400,  /* PAGE_WRITECOMBINE */
954 } MDMemoryProtection;
955 
956 /* Used to mask the mutually exclusive options from the combinable flags. */
957 const uint32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF;
958 
959 /* For (MDRawMemoryInfo).type */
960 typedef enum {
961   MD_MEMORY_TYPE_PRIVATE = 0x20000,   /* not shared by other processes */
962   MD_MEMORY_TYPE_MAPPED  = 0x40000,   /* mapped into the view of a section */
963   MD_MEMORY_TYPE_IMAGE   = 0x1000000  /* mapped into the view of an image */
964 } MDMemoryType;
965 
966 /*
967  * Breakpad extension types
968  */
969 
970 
971 typedef struct {
972   /* validity is a bitmask with values from MDBreakpadInfoValidity, indicating
973    * which of the other fields in the structure are valid. */
974   uint32_t validity;
975 
976   /* Thread ID of the handler thread.  dump_thread_id should correspond to
977    * the thread_id of an MDRawThread in the minidump's MDRawThreadList if
978    * a dedicated thread in that list was used to produce the minidump.  If
979    * the MDRawThreadList does not contain a dedicated thread used to produce
980    * the minidump, this field should be set to 0 and the validity field
981    * must not contain MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID. */
982   uint32_t dump_thread_id;
983 
984   /* Thread ID of the thread that requested the minidump be produced.  As
985    * with dump_thread_id, requesting_thread_id should correspond to the
986    * thread_id of an MDRawThread in the minidump's MDRawThreadList.  For
987    * minidumps produced as a result of an exception, requesting_thread_id
988    * will be the same as the MDRawExceptionStream's thread_id field.  For
989    * minidumps produced "manually" at the program's request,
990    * requesting_thread_id will indicate which thread caused the dump to be
991    * written.  If the minidump was produced at the request of something
992    * other than a thread in the MDRawThreadList, this field should be set
993    * to 0 and the validity field must not contain
994    * MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID. */
995   uint32_t requesting_thread_id;
996 } MDRawBreakpadInfo;
997 
998 /* For (MDRawBreakpadInfo).validity: */
999 typedef enum {
1000   /* When set, the dump_thread_id field is valid. */
1001   MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID       = 1 << 0,
1002 
1003   /* When set, the requesting_thread_id field is valid. */
1004   MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID = 1 << 1
1005 } MDBreakpadInfoValidity;
1006 
1007 typedef struct {
1008   /* expression, function, and file are 0-terminated UTF-16 strings.  They
1009    * may be truncated if necessary, but should always be 0-terminated when
1010    * written to a file.
1011    * Fixed-length strings are used because MiniDumpWriteDump doesn't offer
1012    * a way for user streams to point to arbitrary RVAs for strings. */
1013   uint16_t expression[128];  /* Assertion that failed... */
1014   uint16_t function[128];    /* ...within this function... */
1015   uint16_t file[128];        /* ...in this file... */
1016   uint32_t line;             /* ...at this line. */
1017   uint32_t type;
1018 } MDRawAssertionInfo;
1019 
1020 /* For (MDRawAssertionInfo).type: */
1021 typedef enum {
1022   MD_ASSERTION_INFO_TYPE_UNKNOWN = 0,
1023 
1024   /* Used for assertions that would be raised by the MSVC CRT but are
1025    * directed to an invalid parameter handler instead. */
1026   MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER,
1027 
1028   /* Used for assertions that would be raised by the MSVC CRT but are
1029    * directed to a pure virtual call handler instead. */
1030   MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL
1031 } MDAssertionInfoData;
1032 
1033 /* These structs are used to store the DSO debug data in Linux minidumps,
1034  * which is necessary for converting minidumps to usable coredumps.
1035  * Because of a historical accident, several fields are variably encoded
1036  * according to client word size, so tools potentially need to support both. */
1037 
1038 typedef struct {
1039   uint32_t  addr;
1040   MDRVA     name;
1041   uint32_t  ld;
1042 } MDRawLinkMap32;
1043 
1044 typedef struct {
1045   uint32_t  version;
1046   MDRVA     map;  /* array of MDRawLinkMap32 */
1047   uint32_t  dso_count;
1048   uint32_t  brk;
1049   uint32_t  ldbase;
1050   uint32_t  dynamic;
1051 } MDRawDebug32;
1052 
1053 typedef struct {
1054   uint64_t  addr;
1055   MDRVA     name;
1056   uint64_t  ld;
1057 } MDRawLinkMap64;
1058 
1059 typedef struct {
1060   uint32_t  version;
1061   MDRVA     map;  /* array of MDRawLinkMap64 */
1062   uint32_t  dso_count;
1063   uint64_t  brk;
1064   uint64_t  ldbase;
1065   uint64_t  dynamic;
1066 } MDRawDebug64;
1067 
1068 /* Crashpad extension types. See Crashpad's minidump/minidump_extensions.h. */
1069 
1070 typedef struct {
1071   MDRVA key;
1072   MDRVA value;
1073 } MDRawSimpleStringDictionaryEntry;
1074 
1075 typedef struct {
1076   uint32_t count;
1077   MDRawSimpleStringDictionaryEntry entries[0];
1078 } MDRawSimpleStringDictionary;
1079 
1080 typedef struct {
1081   uint32_t version;
1082   MDLocationDescriptor list_annotations;
1083   MDLocationDescriptor simple_annotations;  /* MDRawSimpleStringDictionary */
1084 } MDRawModuleCrashpadInfo;
1085 
1086 typedef struct {
1087   uint32_t minidump_module_list_index;
1088   MDLocationDescriptor location;  /* MDRawModuleCrashpadInfo */
1089 } MDRawModuleCrashpadInfoLink;
1090 
1091 typedef struct {
1092   uint32_t count;
1093   MDLocationDescriptor modules[0];  /* MDRawModuleCrashpadInfoLink */
1094 } MDRawModuleCrashpadInfoList;
1095 
1096 typedef struct {
1097   uint32_t version;
1098   MDGUID report_id;
1099   MDGUID client_id;
1100   MDLocationDescriptor simple_annotations;  /* MDRawSimpleStringDictionary */
1101   MDLocationDescriptor module_list;  /* MDRawModuleCrashpadInfoList */
1102 } MDRawCrashpadInfo;
1103 
1104 /* macOS __DATA,__crash_info data */
1105 
1106 typedef struct {
1107   uint64_t stream_type; /* MOZ_MACOS_CRASH_INFO_STREAM */
1108   uint64_t version;
1109   uint64_t thread;
1110   uint64_t dialog_mode;
1111   uint64_t abort_cause; /* Only valid when 'version' > 4 */
1112   /* If/when Apple adds more fields to crashreporter_annotations_t, add
1113    * numerical fields here and change (MDRawMacCrashInfo).record_start_size
1114    * accordingly. Make them all uint64_t, to keep this structure the same size
1115    * on all platforms. 'data' should always be the last field. Add new string
1116    * fields to the end of 'data'. */
1117   /* 'data' currently contains five null-terminated uint8_t arrays, each
1118    * possibly empty (containing only a single terminal null), stored one after
1119    * the other:
1120    *   module_path;
1121    *   message;
1122    *   signature_string;
1123    *   backtrace;
1124    *   message2; */
1125   uint8_t data[0];
1126 } MDRawMacCrashInfoRecord;
1127 
1128 typedef struct __attribute__((packed,aligned(4))) {
1129   uint32_t thread_id;
1130   MDRVA64 rva_of_thread_name;
1131 } MDRawThreadName;
1132 
1133 typedef struct {
1134   uint32_t number_of_thread_names;
1135   MDRawThreadName thread_names[0];
1136 } MDRawThreadNamesList;
1137 
1138 /* This is the maximum supported size for each string in
1139  * (MDRawMacCrashInfoRecord).data. If we encounter a string in the
1140  * __crash_info section which seems larger than this, that's a sign of data
1141  * corruption. */
1142 #define MACCRASHINFO_STRING_MAXSIZE 8192
1143 
1144 /* In principle there should only be one or two non-empty __DATA,__crash_info
1145  * sections per process. But the __crash_info section is almost entirely
1146  * undocumented, so just in case we set a large maximum. */
1147 #define MAC_CRASH_INFOS_MAX 20
1148 
1149 typedef struct {
1150   uint32_t stream_type; /* MOZ_MACOS_CRASH_INFO_STREAM */
1151   uint32_t record_count;
1152   /* The size of the "fixed-size" part of MDRawMacCrashInfoRecord, before the
1153    * 'data' field. This will always be 'sizeof(MDRawMacCrashInfoRecord)'. But
1154    * that value may change if more numerical fields are added to
1155    * MDRawMacCrashInfoRecord in the future. */
1156   uint32_t record_start_size;
1157   MDLocationDescriptor records[MAC_CRASH_INFOS_MAX];
1158 } MDRawMacCrashInfo;
1159 
1160 #if defined(_MSC_VER)
1161 #pragma warning(pop)
1162 #endif  /* _MSC_VER */
1163 
1164 
1165 #endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ */
1166