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   u_int32_t data1;
83   u_int16_t data2;
84   u_int16_t data3;
85   u_int8_t  data4[8];
86 } MDGUID;  /* GUID */
87 
88 
89 /*
90  * WinNT.h
91  */
92 
93 /* Non-x86 CPU identifiers found in the high 26 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 #define MD_CONTEXT_AMD64 0x00100000  /* CONTEXT_AMD64 */
99 /* Additional values from winnt.h in the Windows CE 5.0 SDK: */
100 #define MD_CONTEXT_SHX   0x000000c0  /* CONTEXT_SH4 (Super-H, includes SH3) */
101 #define MD_CONTEXT_ARM   0x00000040  /* CONTEXT_ARM (0x40 bit set in SHx?) */
102 #define MD_CONTEXT_MIPS  0x00010000  /* CONTEXT_R4000 (same value as x86?) */
103 #define MD_CONTEXT_ALPHA 0x00020000  /* CONTEXT_ALPHA */
104 
105 #define MD_CONTEXT_CPU_MASK 0xffffffc0
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   u_int32_t context_flags;
113 } MDRawContextBase;
114 
115 #include "minidump_cpu_amd64.h"
116 #include "minidump_cpu_arm.h"
117 #include "minidump_cpu_ppc.h"
118 #include "minidump_cpu_ppc64.h"
119 #include "minidump_cpu_sparc.h"
120 #include "minidump_cpu_x86.h"
121 
122 /*
123  * WinVer.h
124  */
125 
126 
127 typedef struct {
128   u_int32_t signature;
129   u_int32_t struct_version;
130   u_int32_t file_version_hi;
131   u_int32_t file_version_lo;
132   u_int32_t product_version_hi;
133   u_int32_t product_version_lo;
134   u_int32_t file_flags_mask;    /* Identifies valid bits in fileFlags */
135   u_int32_t file_flags;
136   u_int32_t file_os;
137   u_int32_t file_type;
138   u_int32_t file_subtype;
139   u_int32_t file_date_hi;
140   u_int32_t file_date_lo;
141 } MDVSFixedFileInfo;  /* VS_FIXEDFILEINFO */
142 
143 /* For (MDVSFixedFileInfo).signature */
144 #define MD_VSFIXEDFILEINFO_SIGNATURE 0xfeef04bd
145      /* VS_FFI_SIGNATURE */
146 
147 /* For (MDVSFixedFileInfo).version */
148 #define MD_VSFIXEDFILEINFO_VERSION 0x00010000
149      /* VS_FFI_STRUCVERSION */
150 
151 /* For (MDVSFixedFileInfo).file_flags_mask and
152  * (MDVSFixedFileInfo).file_flags */
153 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG        0x00000001
154      /* VS_FF_DEBUG */
155 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRERELEASE   0x00000002
156      /* VS_FF_PRERELEASE */
157 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_PATCHED      0x00000004
158      /* VS_FF_PATCHED */
159 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_PRIVATEBUILD 0x00000008
160      /* VS_FF_PRIVATEBUILD */
161 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_INFOINFERRED 0x00000010
162      /* VS_FF_INFOINFERRED */
163 #define MD_VSFIXEDFILEINFO_FILE_FLAGS_SPECIALBUILD 0x00000020
164      /* VS_FF_SPECIALBUILD */
165 
166 /* For (MDVSFixedFileInfo).file_os: high 16 bits */
167 #define MD_VSFIXEDFILEINFO_FILE_OS_UNKNOWN    0          /* VOS_UNKNOWN */
168 #define MD_VSFIXEDFILEINFO_FILE_OS_DOS        (1 << 16)  /* VOS_DOS */
169 #define MD_VSFIXEDFILEINFO_FILE_OS_OS216      (2 << 16)  /* VOS_OS216 */
170 #define MD_VSFIXEDFILEINFO_FILE_OS_OS232      (3 << 16)  /* VOS_OS232 */
171 #define MD_VSFIXEDFILEINFO_FILE_OS_NT         (4 << 16)  /* VOS_NT */
172 #define MD_VSFIXEDFILEINFO_FILE_OS_WINCE      (5 << 16)  /* VOS_WINCE */
173 /* Low 16 bits */
174 #define MD_VSFIXEDFILEINFO_FILE_OS__BASE      0          /* VOS__BASE */
175 #define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS16 1          /* VOS__WINDOWS16 */
176 #define MD_VSFIXEDFILEINFO_FILE_OS__PM16      2          /* VOS__PM16 */
177 #define MD_VSFIXEDFILEINFO_FILE_OS__PM32      3          /* VOS__PM32 */
178 #define MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32 4          /* VOS__WINDOWS32 */
179 
180 /* For (MDVSFixedFileInfo).file_type */
181 #define MD_VSFIXEDFILEINFO_FILE_TYPE_UNKNOWN    0  /* VFT_UNKNOWN */
182 #define MD_VSFIXEDFILEINFO_FILE_TYPE_APP        1  /* VFT_APP */
183 #define MD_VSFIXEDFILEINFO_FILE_TYPE_DLL        2  /* VFT_DLL */
184 #define MD_VSFIXEDFILEINFO_FILE_TYPE_DRV        3  /* VFT_DLL */
185 #define MD_VSFIXEDFILEINFO_FILE_TYPE_FONT       4  /* VFT_FONT */
186 #define MD_VSFIXEDFILEINFO_FILE_TYPE_VXD        5  /* VFT_VXD */
187 #define MD_VSFIXEDFILEINFO_FILE_TYPE_STATIC_LIB 7  /* VFT_STATIC_LIB */
188 
189 /* For (MDVSFixedFileInfo).file_subtype */
190 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN                0
191      /* VFT2_UNKNOWN */
192 /* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_DRV */
193 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_PRINTER            1
194      /* VFT2_DRV_PRINTER */
195 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_KEYBOARD           2
196      /* VFT2_DRV_KEYBOARD */
197 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_LANGUAGE           3
198      /* VFT2_DRV_LANGUAGE */
199 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_DISPLAY            4
200      /* VFT2_DRV_DISPLAY */
201 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_MOUSE              5
202      /* VFT2_DRV_MOUSE */
203 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_NETWORK            6
204      /* VFT2_DRV_NETWORK */
205 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SYSTEM             7
206      /* VFT2_DRV_SYSTEM */
207 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INSTALLABLE        8
208      /* VFT2_DRV_INSTALLABLE */
209 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_SOUND              9
210      /* VFT2_DRV_SOUND */
211 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_COMM              10
212      /* VFT2_DRV_COMM */
213 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_INPUTMETHOD       11
214      /* VFT2_DRV_INPUTMETHOD */
215 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_DRV_VERSIONED_PRINTER 12
216      /* VFT2_DRV_VERSIONED_PRINTER */
217 /* with file_type = MD_VSFIXEDFILEINFO_FILETYPE_FONT */
218 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_RASTER            1
219      /* VFT2_FONT_RASTER */
220 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_VECTOR            2
221      /* VFT2_FONT_VECTOR */
222 #define MD_VSFIXEDFILEINFO_FILE_SUBTYPE_FONT_TRUETYPE          3
223      /* VFT2_FONT_TRUETYPE */
224 
225 
226 /*
227  * DbgHelp.h
228  */
229 
230 
231 /* An MDRVA is an offset into the minidump file.  The beginning of the
232  * MDRawHeader is at offset 0. */
233 typedef u_int32_t MDRVA;  /* RVA */
234 
235 typedef struct {
236   u_int32_t data_size;
237   MDRVA     rva;
238 } MDLocationDescriptor;  /* MINIDUMP_LOCATION_DESCRIPTOR */
239 
240 
241 typedef struct {
242   /* The base address of the memory range on the host that produced the
243    * minidump. */
244   u_int64_t            start_of_memory_range;
245 
246   MDLocationDescriptor memory;
247 } MDMemoryDescriptor;  /* MINIDUMP_MEMORY_DESCRIPTOR */
248 
249 
250 typedef struct {
251   u_int32_t signature;
252   u_int32_t version;
253   u_int32_t stream_count;
254   MDRVA     stream_directory_rva;  /* A |stream_count|-sized array of
255                                     * MDRawDirectory structures. */
256   u_int32_t checksum;              /* Can be 0.  In fact, that's all that's
257                                     * been found in minidump files. */
258   u_int32_t time_date_stamp;       /* time_t */
259   u_int64_t flags;
260 } MDRawHeader;  /* MINIDUMP_HEADER */
261 
262 /* For (MDRawHeader).signature and (MDRawHeader).version.  Note that only the
263  * low 16 bits of (MDRawHeader).version are MD_HEADER_VERSION.  Per the
264  * documentation, the high 16 bits are implementation-specific. */
265 #define MD_HEADER_SIGNATURE 0x504d444d /* 'PMDM' */
266      /* MINIDUMP_SIGNATURE */
267 #define MD_HEADER_VERSION   0x0000a793 /* 42899 */
268      /* MINIDUMP_VERSION */
269 
270 /* For (MDRawHeader).flags: */
271 typedef enum {
272   /* MD_NORMAL is the standard type of minidump.  It includes full
273    * streams for the thread list, module list, exception, system info,
274    * and miscellaneous info.  A memory list stream is also present,
275    * pointing to the same stack memory contained in the thread list,
276    * as well as a 256-byte region around the instruction address that
277    * was executing when the exception occurred.  Stack memory is from
278    * 4 bytes below a thread's stack pointer up to the top of the
279    * memory region encompassing the stack. */
280   MD_NORMAL                            = 0x00000000,
281   MD_WITH_DATA_SEGS                    = 0x00000001,
282   MD_WITH_FULL_MEMORY                  = 0x00000002,
283   MD_WITH_HANDLE_DATA                  = 0x00000004,
284   MD_FILTER_MEMORY                     = 0x00000008,
285   MD_SCAN_MEMORY                       = 0x00000010,
286   MD_WITH_UNLOADED_MODULES             = 0x00000020,
287   MD_WITH_INDIRECTLY_REFERENCED_MEMORY = 0x00000040,
288   MD_FILTER_MODULE_PATHS               = 0x00000080,
289   MD_WITH_PROCESS_THREAD_DATA          = 0x00000100,
290   MD_WITH_PRIVATE_READ_WRITE_MEMORY    = 0x00000200,
291   MD_WITHOUT_OPTIONAL_DATA             = 0x00000400,
292   MD_WITH_FULL_MEMORY_INFO             = 0x00000800,
293   MD_WITH_THREAD_INFO                  = 0x00001000,
294   MD_WITH_CODE_SEGS                    = 0x00002000,
295   MD_WITHOUT_AUXILLIARY_SEGS           = 0x00004000,
296   MD_WITH_FULL_AUXILLIARY_STATE        = 0x00008000,
297   MD_WITH_PRIVATE_WRITE_COPY_MEMORY    = 0x00010000,
298   MD_IGNORE_INACCESSIBLE_MEMORY        = 0x00020000,
299   MD_WITH_TOKEN_INFORMATION            = 0x00040000
300 } MDType;  /* MINIDUMP_TYPE */
301 
302 
303 typedef struct {
304   u_int32_t            stream_type;
305   MDLocationDescriptor location;
306 } MDRawDirectory;  /* MINIDUMP_DIRECTORY */
307 
308 /* For (MDRawDirectory).stream_type */
309 typedef enum {
310   MD_UNUSED_STREAM               =  0,
311   MD_RESERVED_STREAM_0           =  1,
312   MD_RESERVED_STREAM_1           =  2,
313   MD_THREAD_LIST_STREAM          =  3,  /* MDRawThreadList */
314   MD_MODULE_LIST_STREAM          =  4,  /* MDRawModuleList */
315   MD_MEMORY_LIST_STREAM          =  5,  /* MDRawMemoryList */
316   MD_EXCEPTION_STREAM            =  6,  /* MDRawExceptionStream */
317   MD_SYSTEM_INFO_STREAM          =  7,  /* MDRawSystemInfo */
318   MD_THREAD_EX_LIST_STREAM       =  8,
319   MD_MEMORY_64_LIST_STREAM       =  9,
320   MD_COMMENT_STREAM_A            = 10,
321   MD_COMMENT_STREAM_W            = 11,
322   MD_HANDLE_DATA_STREAM          = 12,
323   MD_FUNCTION_TABLE_STREAM       = 13,
324   MD_UNLOADED_MODULE_LIST_STREAM = 14,
325   MD_MISC_INFO_STREAM            = 15,  /* MDRawMiscInfo */
326   MD_MEMORY_INFO_LIST_STREAM     = 16,  /* MDRawMemoryInfoList */
327   MD_THREAD_INFO_LIST_STREAM     = 17,
328   MD_HANDLE_OPERATION_LIST_STREAM = 18,
329   MD_LAST_RESERVED_STREAM        = 0x0000ffff,
330 
331   /* Breakpad extension types.  0x4767 = "Gg" */
332   MD_BREAKPAD_INFO_STREAM        = 0x47670001,  /* MDRawBreakpadInfo */
333   MD_ASSERTION_INFO_STREAM       = 0x47670002   /* MDRawAssertionInfo */
334 } MDStreamType;  /* MINIDUMP_STREAM_TYPE */
335 
336 
337 typedef struct {
338   u_int32_t length;     /* Length of buffer in bytes (not characters),
339                          * excluding 0-terminator */
340   u_int16_t buffer[1];  /* UTF-16-encoded, 0-terminated */
341 } MDString;  /* MINIDUMP_STRING */
342 
343 static const size_t MDString_minsize = offsetof(MDString, buffer[0]);
344 
345 
346 typedef struct {
347   u_int32_t            thread_id;
348   u_int32_t            suspend_count;
349   u_int32_t            priority_class;
350   u_int32_t            priority;
351   u_int64_t            teb;             /* Thread environment block */
352   MDMemoryDescriptor   stack;
353   MDLocationDescriptor thread_context;  /* MDRawContext[CPU] */
354 } MDRawThread;  /* MINIDUMP_THREAD */
355 
356 
357 typedef struct {
358   u_int32_t   number_of_threads;
359   MDRawThread threads[1];
360 } MDRawThreadList;  /* MINIDUMP_THREAD_LIST */
361 
362 static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList,
363                                                        threads[0]);
364 
365 
366 typedef struct {
367   u_int64_t            base_of_image;
368   u_int32_t            size_of_image;
369   u_int32_t            checksum;         /* 0 if unknown */
370   u_int32_t            time_date_stamp;  /* time_t */
371   MDRVA                module_name_rva;  /* MDString, pathname or filename */
372   MDVSFixedFileInfo    version_info;
373 
374   /* The next field stores a CodeView record and is populated when a module's
375    * debug information resides in a PDB file.  It identifies the PDB file. */
376   MDLocationDescriptor cv_record;
377 
378   /* The next field is populated when a module's debug information resides
379    * in a DBG file.  It identifies the DBG file.  This field is effectively
380    * obsolete with modules built by recent toolchains. */
381   MDLocationDescriptor misc_record;
382 
383   /* Alignment problem: reserved0 and reserved1 are defined by the platform
384    * SDK as 64-bit quantities.  However, that results in a structure whose
385    * alignment is unpredictable on different CPUs and ABIs.  If the ABI
386    * specifies full alignment of 64-bit quantities in structures (as ppc
387    * does), there will be padding between miscRecord and reserved0.  If
388    * 64-bit quantities can be aligned on 32-bit boundaries (as on x86),
389    * this padding will not exist.  (Note that the structure up to this point
390    * contains 1 64-bit member followed by 21 32-bit members.)
391    * As a workaround, reserved0 and reserved1 are instead defined here as
392    * four 32-bit quantities.  This should be harmless, as there are
393    * currently no known uses for these fields. */
394   u_int32_t            reserved0[2];
395   u_int32_t            reserved1[2];
396 } MDRawModule;  /* MINIDUMP_MODULE */
397 
398 /* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to
399  * be tail-padded out to a multiple of 64 bits under some ABIs (such as PPC).
400  * This doesn't occur on systems that don't tail-pad in this manner.  Define
401  * this macro to be the usable size of the MDRawModule struct, and use it in
402  * place of sizeof(MDRawModule). */
403 #define MD_MODULE_SIZE 108
404 
405 
406 /* (MDRawModule).cv_record can reference MDCVInfoPDB20 or MDCVInfoPDB70.
407  * Ref.: http://www.debuginfo.com/articles/debuginfomatch.html
408  * MDCVInfoPDB70 is the expected structure type with recent toolchains. */
409 
410 typedef struct {
411   u_int32_t signature;
412   u_int32_t offset;     /* Offset to debug data (expect 0 in minidump) */
413 } MDCVHeader;
414 
415 typedef struct {
416   MDCVHeader cv_header;
417   u_int32_t  signature;         /* time_t debug information created */
418   u_int32_t  age;               /* revision of PDB file */
419   u_int8_t   pdb_file_name[1];  /* Pathname or filename of PDB file */
420 } MDCVInfoPDB20;
421 
422 static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20,
423                                                      pdb_file_name[0]);
424 
425 #define MD_CVINFOPDB20_SIGNATURE 0x3031424e  /* cvHeader.signature = '01BN' */
426 
427 typedef struct {
428   u_int32_t cv_signature;
429   MDGUID    signature;         /* GUID, identifies PDB file */
430   u_int32_t age;               /* Identifies incremental changes to PDB file */
431   u_int8_t  pdb_file_name[1];  /* Pathname or filename of PDB file,
432                                 * 0-terminated 8-bit character data (UTF-8?) */
433 } MDCVInfoPDB70;
434 
435 static const size_t MDCVInfoPDB70_minsize = offsetof(MDCVInfoPDB70,
436                                                      pdb_file_name[0]);
437 
438 #define MD_CVINFOPDB70_SIGNATURE 0x53445352  /* cvSignature = 'SDSR' */
439 
440 typedef struct {
441   u_int32_t data1[2];
442   u_int32_t data2;
443   u_int32_t data3;
444   u_int32_t data4;
445   u_int32_t data5[3];
446   u_int8_t extra[2];
447 } MDCVInfoELF;
448 
449 /* In addition to the two CodeView record formats above, used for linking
450  * to external pdb files, it is possible for debugging data to be carried
451  * directly in the CodeView record itself.  These signature values will
452  * be found in the first 4 bytes of the CodeView record.  Additional values
453  * not commonly experienced in the wild are given by "Microsoft Symbol and
454  * Type Information", http://www.x86.org/ftp/manuals/tools/sym.pdf, section
455  * 7.2.  An in-depth description of the CodeView 4.1 format is given by
456  * "Undocumented Windows 2000 Secrets", Windows 2000 Debugging Support/
457  * Microsoft Symbol File Internals/CodeView Subsections,
458  * http://www.rawol.com/features/undocumented/sbs-w2k-1-windows-2000-debugging-support.pdf
459  */
460 #define MD_CVINFOCV41_SIGNATURE 0x3930424e  /* '90BN', CodeView 4.10. */
461 #define MD_CVINFOCV50_SIGNATURE 0x3131424e  /* '11BN', CodeView 5.0,
462                                              * MS C7-format (/Z7). */
463 
464 #define MD_CVINFOUNKNOWN_SIGNATURE 0xffffffff  /* An unlikely value. */
465 
466 /* (MDRawModule).miscRecord can reference MDImageDebugMisc.  The Windows
467  * structure is actually defined in WinNT.h.  This structure is effectively
468  * obsolete with modules built by recent toolchains. */
469 
470 typedef struct {
471   u_int32_t data_type;    /* IMAGE_DEBUG_TYPE_*, not defined here because
472                            * this debug record type is mostly obsolete. */
473   u_int32_t length;       /* Length of entire MDImageDebugMisc structure */
474   u_int8_t  unicode;      /* True if data is multibyte */
475   u_int8_t  reserved[3];
476   u_int8_t  data[1];
477 } MDImageDebugMisc;  /* IMAGE_DEBUG_MISC */
478 
479 static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc,
480                                                         data[0]);
481 
482 
483 typedef struct {
484   u_int32_t   number_of_modules;
485   MDRawModule modules[1];
486 } MDRawModuleList;  /* MINIDUMP_MODULE_LIST */
487 
488 static const size_t MDRawModuleList_minsize = offsetof(MDRawModuleList,
489                                                        modules[0]);
490 
491 
492 typedef struct {
493   u_int32_t          number_of_memory_ranges;
494   MDMemoryDescriptor memory_ranges[1];
495 } MDRawMemoryList;  /* MINIDUMP_MEMORY_LIST */
496 
497 static const size_t MDRawMemoryList_minsize = offsetof(MDRawMemoryList,
498                                                        memory_ranges[0]);
499 
500 
501 #define MD_EXCEPTION_MAXIMUM_PARAMETERS 15
502 
503 typedef struct {
504   u_int32_t exception_code;     /* Windows: MDExceptionCodeWin,
505                                  * Mac OS X: MDExceptionMac,
506                                  * Linux: MDExceptionCodeLinux. */
507   u_int32_t exception_flags;    /* Windows: 1 if noncontinuable,
508                                    Mac OS X: MDExceptionCodeMac. */
509   u_int64_t exception_record;   /* Address (in the minidump-producing host's
510                                  * memory) of another MDException, for
511                                  * nested exceptions. */
512   u_int64_t exception_address;  /* The address that caused the exception.
513                                  * Mac OS X: exception subcode (which is
514                                  *           typically the address). */
515   u_int32_t number_parameters;  /* Number of valid elements in
516                                  * exception_information. */
517   u_int32_t __align;
518   u_int64_t exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS];
519 } MDException;  /* MINIDUMP_EXCEPTION */
520 
521 #include "minidump_exception_win32.h"
522 #include "minidump_exception_mac.h"
523 #include "minidump_exception_linux.h"
524 #include "minidump_exception_solaris.h"
525 
526 typedef struct {
527   u_int32_t            thread_id;         /* Thread in which the exception
528                                            * occurred.  Corresponds to
529                                            * (MDRawThread).thread_id. */
530   u_int32_t            __align;
531   MDException          exception_record;
532   MDLocationDescriptor thread_context;    /* MDRawContext[CPU] */
533 } MDRawExceptionStream;  /* MINIDUMP_EXCEPTION_STREAM */
534 
535 
536 typedef union {
537   struct {
538     u_int32_t vendor_id[3];               /* cpuid 0: ebx, edx, ecx */
539     u_int32_t version_information;        /* cpuid 1: eax */
540     u_int32_t feature_information;        /* cpuid 1: edx */
541     u_int32_t amd_extended_cpu_features;  /* cpuid 0x80000001, ebx */
542   } x86_cpu_info;
543   struct {
544     u_int64_t processor_features[2];
545   } other_cpu_info;
546 } MDCPUInformation;  /* CPU_INFORMATION */
547 
548 
549 typedef struct {
550   /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO
551    * structure as returned by GetSystemInfo */
552   u_int16_t        processor_architecture;
553   u_int16_t        processor_level;         /* x86: 5 = 586, 6 = 686, ... */
554   u_int16_t        processor_revision;      /* x86: 0xMMSS, where MM=model,
555                                              *      SS=stepping */
556 
557   u_int8_t         number_of_processors;
558   u_int8_t         product_type;            /* Windows: VER_NT_* from WinNT.h */
559 
560   /* The next 5 fields are from the OSVERSIONINFO structure as returned
561    * by GetVersionEx */
562   u_int32_t        major_version;
563   u_int32_t        minor_version;
564   u_int32_t        build_number;
565   u_int32_t        platform_id;
566   MDRVA            csd_version_rva;  /* MDString further identifying the
567                                       * host OS.
568                                       * Windows: name of the installed OS
569                                       *          service pack.
570                                       * Mac OS X: the Apple OS build number
571                                       *           (sw_vers -buildVersion).
572                                       * Linux: uname -srvmo */
573 
574   u_int16_t        suite_mask;       /* Windows: VER_SUITE_* from WinNT.h */
575   u_int16_t        reserved2;
576 
577   MDCPUInformation cpu;
578 } MDRawSystemInfo;  /* MINIDUMP_SYSTEM_INFO */
579 
580 /* For (MDRawSystemInfo).processor_architecture: */
581 typedef enum {
582   MD_CPU_ARCHITECTURE_X86       =  0,  /* PROCESSOR_ARCHITECTURE_INTEL */
583   MD_CPU_ARCHITECTURE_MIPS      =  1,  /* PROCESSOR_ARCHITECTURE_MIPS */
584   MD_CPU_ARCHITECTURE_ALPHA     =  2,  /* PROCESSOR_ARCHITECTURE_ALPHA */
585   MD_CPU_ARCHITECTURE_PPC       =  3,  /* PROCESSOR_ARCHITECTURE_PPC */
586   MD_CPU_ARCHITECTURE_SHX       =  4,  /* PROCESSOR_ARCHITECTURE_SHX
587                                         * (Super-H) */
588   MD_CPU_ARCHITECTURE_ARM       =  5,  /* PROCESSOR_ARCHITECTURE_ARM */
589   MD_CPU_ARCHITECTURE_IA64      =  6,  /* PROCESSOR_ARCHITECTURE_IA64 */
590   MD_CPU_ARCHITECTURE_ALPHA64   =  7,  /* PROCESSOR_ARCHITECTURE_ALPHA64 */
591   MD_CPU_ARCHITECTURE_MSIL      =  8,  /* PROCESSOR_ARCHITECTURE_MSIL
592                                         * (Microsoft Intermediate Language) */
593   MD_CPU_ARCHITECTURE_AMD64     =  9,  /* PROCESSOR_ARCHITECTURE_AMD64 */
594   MD_CPU_ARCHITECTURE_X86_WIN64 = 10,
595       /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
596   MD_CPU_ARCHITECTURE_SPARC     = 0x8001, /* Breakpad-defined value for SPARC */
597   MD_CPU_ARCHITECTURE_UNKNOWN   = 0xffff  /* PROCESSOR_ARCHITECTURE_UNKNOWN */
598 } MDCPUArchitecture;
599 
600 /* For (MDRawSystemInfo).platform_id: */
601 typedef enum {
602   MD_OS_WIN32S        = 0,  /* VER_PLATFORM_WIN32s (Windows 3.1) */
603   MD_OS_WIN32_WINDOWS = 1,  /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
604   MD_OS_WIN32_NT      = 2,  /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
605   MD_OS_WIN32_CE      = 3,  /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
606                              * (Windows CE, Windows Mobile, "Handheld") */
607 
608   /* The following values are Breakpad-defined. */
609   MD_OS_UNIX          = 0x8000,  /* Generic Unix-ish */
610   MD_OS_MAC_OS_X      = 0x8101,  /* Mac OS X/Darwin */
611   MD_OS_LINUX         = 0x8201,  /* Linux */
612   MD_OS_SOLARIS       = 0x8202   /* Solaris */
613 } MDOSPlatform;
614 
615 
616 typedef struct {
617   u_int32_t size_of_info;  /* Length of entire MDRawMiscInfo structure. */
618   u_int32_t flags1;
619 
620   /* The next field is only valid if flags1 contains
621    * MD_MISCINFO_FLAGS1_PROCESS_ID. */
622   u_int32_t process_id;
623 
624   /* The next 3 fields are only valid if flags1 contains
625    * MD_MISCINFO_FLAGS1_PROCESS_TIMES. */
626   u_int32_t process_create_time;  /* time_t process started */
627   u_int32_t process_user_time;    /* seconds of user CPU time */
628   u_int32_t process_kernel_time;  /* seconds of kernel CPU time */
629 
630   /* The following fields are not present in MINIDUMP_MISC_INFO but are
631    * in MINIDUMP_MISC_INFO_2.  When this struct is populated, these values
632    * may not be set.  Use flags1 or sizeOfInfo to determine whether these
633    * values are present.  These are only valid when flags1 contains
634    * MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
635   u_int32_t processor_max_mhz;
636   u_int32_t processor_current_mhz;
637   u_int32_t processor_mhz_limit;
638   u_int32_t processor_max_idle_state;
639   u_int32_t processor_current_idle_state;
640 } MDRawMiscInfo;  /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO2 */
641 
642 #define MD_MISCINFO_SIZE 24
643 #define MD_MISCINFO2_SIZE 44
644 
645 /* For (MDRawMiscInfo).flags1.  These values indicate which fields in the
646  * MDRawMiscInfoStructure are valid. */
647 typedef enum {
648   MD_MISCINFO_FLAGS1_PROCESS_ID           = 0x00000001,
649       /* MINIDUMP_MISC1_PROCESS_ID */
650   MD_MISCINFO_FLAGS1_PROCESS_TIMES        = 0x00000002,
651       /* MINIDUMP_MISC1_PROCESS_TIMES */
652   MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO = 0x00000004
653       /* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
654 } MDMiscInfoFlags1;
655 
656 /*
657  * Around DbgHelp version 6.0, the style of new LIST structures changed
658  * from including an array of length 1 at the end of the struct to
659  * represent the variable-length data to including explicit
660  * "size of header", "size of entry" and "number of entries" fields
661  * in the header, presumably to allow backwards-compatibly-extending
662  * the structures in the future. The actual list entries follow the
663  * header data directly in this case.
664  */
665 
666 typedef struct {
667   u_int32_t size_of_header;    /* sizeof(MDRawMemoryInfoList) */
668   u_int32_t size_of_entry;     /* sizeof(MDRawMemoryInfo) */
669   u_int64_t number_of_entries;
670 } MDRawMemoryInfoList;  /* MINIDUMP_MEMORY_INFO_LIST */
671 
672 typedef struct {
673   u_int64_t base_address;           /* Base address of a region of pages */
674   u_int64_t allocation_base;        /* Base address of a range of pages
675                                      * within this region. */
676   u_int32_t allocation_protection;  /* Memory protection when this region
677                                      * was originally allocated:
678                                      * MDMemoryProtection */
679   u_int32_t __alignment1;
680   u_int64_t region_size;
681   u_int32_t state;                  /* MDMemoryState */
682   u_int32_t protection;             /* MDMemoryProtection */
683   u_int32_t type;                   /* MDMemoryType */
684   u_int32_t __alignment2;
685 } MDRawMemoryInfo;  /* MINIDUMP_MEMORY_INFO */
686 
687 /* For (MDRawMemoryInfo).state */
688 typedef enum {
689   MD_MEMORY_STATE_COMMIT   = 0x1000,  /* physical storage has been allocated */
690   MD_MEMORY_STATE_RESERVE  = 0x2000,  /* reserved, but no physical storage */
691   MD_MEMORY_STATE_FREE     = 0x10000  /* available to be allocated */
692 } MDMemoryState;
693 
694 /* For (MDRawMemoryInfo).allocation_protection and .protection */
695 typedef enum {
696   MD_MEMORY_PROTECT_NOACCESS          = 0x01,  /* PAGE_NOACCESS */
697   MD_MEMORY_PROTECT_READONLY          = 0x02,  /* PAGE_READONLY */
698   MD_MEMORY_PROTECT_READWRITE         = 0x04,  /* PAGE_READWRITE */
699   MD_MEMORY_PROTECT_WRITECOPY         = 0x08,  /* PAGE_WRITECOPY */
700   MD_MEMORY_PROTECT_EXECUTE           = 0x10,  /* PAGE_EXECUTE */
701   MD_MEMORY_PROTECT_EXECUTE_READ      = 0x20,  /* PAGE_EXECUTE_READ */
702   MD_MEMORY_PROTECT_EXECUTE_READWRITE = 0x40,  /* PAGE_EXECUTE_READWRITE */
703   MD_MEMORY_PROTECT_EXECUTE_WRITECOPY = 0x80,  /* PAGE_EXECUTE_WRITECOPY */
704   /* These options can be combined with the previous flags. */
705   MD_MEMORY_PROTECT_GUARD             = 0x100,  /* PAGE_GUARD */
706   MD_MEMORY_PROTECT_NOCACHE           = 0x200,  /* PAGE_NOCACHE */
707   MD_MEMORY_PROTECT_WRITECOMBINE      = 0x400,  /* PAGE_WRITECOMBINE */
708 } MDMemoryProtection;
709 
710 /* Used to mask the mutually exclusive options from the combinable flags. */
711 const u_int32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF;
712 
713 /* For (MDRawMemoryInfo).type */
714 typedef enum {
715   MD_MEMORY_TYPE_PRIVATE = 0x20000,   /* not shared by other processes */
716   MD_MEMORY_TYPE_MAPPED  = 0x40000,   /* mapped into the view of a section */
717   MD_MEMORY_TYPE_IMAGE   = 0x1000000  /* mapped into the view of an image */
718 } MDMemoryType;
719 
720 /*
721  * Breakpad extension types
722  */
723 
724 
725 typedef struct {
726   /* validity is a bitmask with values from MDBreakpadInfoValidity, indicating
727    * which of the other fields in the structure are valid. */
728   u_int32_t validity;
729 
730   /* Thread ID of the handler thread.  dump_thread_id should correspond to
731    * the thread_id of an MDRawThread in the minidump's MDRawThreadList if
732    * a dedicated thread in that list was used to produce the minidump.  If
733    * the MDRawThreadList does not contain a dedicated thread used to produce
734    * the minidump, this field should be set to 0 and the validity field
735    * must not contain MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID. */
736   u_int32_t dump_thread_id;
737 
738   /* Thread ID of the thread that requested the minidump be produced.  As
739    * with dump_thread_id, requesting_thread_id should correspond to the
740    * thread_id of an MDRawThread in the minidump's MDRawThreadList.  For
741    * minidumps produced as a result of an exception, requesting_thread_id
742    * will be the same as the MDRawExceptionStream's thread_id field.  For
743    * minidumps produced "manually" at the program's request,
744    * requesting_thread_id will indicate which thread caused the dump to be
745    * written.  If the minidump was produced at the request of something
746    * other than a thread in the MDRawThreadList, this field should be set
747    * to 0 and the validity field must not contain
748    * MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID. */
749   u_int32_t requesting_thread_id;
750 } MDRawBreakpadInfo;
751 
752 /* For (MDRawBreakpadInfo).validity: */
753 typedef enum {
754   /* When set, the dump_thread_id field is valid. */
755   MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID       = 1 << 0,
756 
757   /* When set, the requesting_thread_id field is valid. */
758   MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID = 1 << 1
759 } MDBreakpadInfoValidity;
760 
761 typedef struct {
762   /* expression, function, and file are 0-terminated UTF-16 strings.  They
763    * may be truncated if necessary, but should always be 0-terminated when
764    * written to a file.
765    * Fixed-length strings are used because MiniDumpWriteDump doesn't offer
766    * a way for user streams to point to arbitrary RVAs for strings. */
767   u_int16_t expression[128];  /* Assertion that failed... */
768   u_int16_t function[128];    /* ...within this function... */
769   u_int16_t file[128];        /* ...in this file... */
770   u_int32_t line;             /* ...at this line. */
771   u_int32_t type;
772 } MDRawAssertionInfo;
773 
774 /* For (MDRawAssertionInfo).type: */
775 typedef enum {
776   MD_ASSERTION_INFO_TYPE_UNKNOWN = 0,
777 
778   /* Used for assertions that would be raised by the MSVC CRT but are
779    * directed to an invalid parameter handler instead. */
780   MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER,
781 
782   /* Used for assertions that would be raised by the MSVC CRT but are
783    * directed to a pure virtual call handler instead. */
784   MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL
785 } MDAssertionInfoData;
786 
787 #if defined(_MSC_VER)
788 #pragma warning(pop)
789 #endif  /* _MSC_VER */
790 
791 
792 #endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ */
793