Home | History | Annotate | Download | only in common
      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 
    237 typedef struct {
    238   uint32_t  data_size;
    239   MDRVA     rva;
    240 } MDLocationDescriptor;  /* MINIDUMP_LOCATION_DESCRIPTOR */
    241 
    242 
    243 typedef struct {
    244   /* The base address of the memory range on the host that produced the
    245    * minidump. */
    246   uint64_t             start_of_memory_range;
    247 
    248   MDLocationDescriptor memory;
    249 } MDMemoryDescriptor;  /* MINIDUMP_MEMORY_DESCRIPTOR */
    250 
    251 
    252 typedef struct {
    253   uint32_t  signature;
    254   uint32_t  version;
    255   uint32_t  stream_count;
    256   MDRVA     stream_directory_rva;  /* A |stream_count|-sized array of
    257                                     * MDRawDirectory structures. */
    258   uint32_t  checksum;              /* Can be 0.  In fact, that's all that's
    259                                     * been found in minidump files. */
    260   uint32_t  time_date_stamp;       /* time_t */
    261   uint64_t  flags;
    262 } MDRawHeader;  /* MINIDUMP_HEADER */
    263 
    264 /* For (MDRawHeader).signature and (MDRawHeader).version.  Note that only the
    265  * low 16 bits of (MDRawHeader).version are MD_HEADER_VERSION.  Per the
    266  * documentation, the high 16 bits are implementation-specific. */
    267 #define MD_HEADER_SIGNATURE 0x504d444d /* 'PMDM' */
    268      /* MINIDUMP_SIGNATURE */
    269 #define MD_HEADER_VERSION   0x0000a793 /* 42899 */
    270      /* MINIDUMP_VERSION */
    271 
    272 /* For (MDRawHeader).flags: */
    273 typedef enum {
    274   /* MD_NORMAL is the standard type of minidump.  It includes full
    275    * streams for the thread list, module list, exception, system info,
    276    * and miscellaneous info.  A memory list stream is also present,
    277    * pointing to the same stack memory contained in the thread list,
    278    * as well as a 256-byte region around the instruction address that
    279    * was executing when the exception occurred.  Stack memory is from
    280    * 4 bytes below a thread's stack pointer up to the top of the
    281    * memory region encompassing the stack. */
    282   MD_NORMAL                            = 0x00000000,
    283   MD_WITH_DATA_SEGS                    = 0x00000001,
    284   MD_WITH_FULL_MEMORY                  = 0x00000002,
    285   MD_WITH_HANDLE_DATA                  = 0x00000004,
    286   MD_FILTER_MEMORY                     = 0x00000008,
    287   MD_SCAN_MEMORY                       = 0x00000010,
    288   MD_WITH_UNLOADED_MODULES             = 0x00000020,
    289   MD_WITH_INDIRECTLY_REFERENCED_MEMORY = 0x00000040,
    290   MD_FILTER_MODULE_PATHS               = 0x00000080,
    291   MD_WITH_PROCESS_THREAD_DATA          = 0x00000100,
    292   MD_WITH_PRIVATE_READ_WRITE_MEMORY    = 0x00000200,
    293   MD_WITHOUT_OPTIONAL_DATA             = 0x00000400,
    294   MD_WITH_FULL_MEMORY_INFO             = 0x00000800,
    295   MD_WITH_THREAD_INFO                  = 0x00001000,
    296   MD_WITH_CODE_SEGS                    = 0x00002000,
    297   MD_WITHOUT_AUXILLIARY_SEGS           = 0x00004000,
    298   MD_WITH_FULL_AUXILLIARY_STATE        = 0x00008000,
    299   MD_WITH_PRIVATE_WRITE_COPY_MEMORY    = 0x00010000,
    300   MD_IGNORE_INACCESSIBLE_MEMORY        = 0x00020000,
    301   MD_WITH_TOKEN_INFORMATION            = 0x00040000
    302 } MDType;  /* MINIDUMP_TYPE */
    303 
    304 
    305 typedef struct {
    306   uint32_t             stream_type;
    307   MDLocationDescriptor location;
    308 } MDRawDirectory;  /* MINIDUMP_DIRECTORY */
    309 
    310 /* For (MDRawDirectory).stream_type */
    311 typedef enum {
    312   MD_UNUSED_STREAM               =  0,
    313   MD_RESERVED_STREAM_0           =  1,
    314   MD_RESERVED_STREAM_1           =  2,
    315   MD_THREAD_LIST_STREAM          =  3,  /* MDRawThreadList */
    316   MD_MODULE_LIST_STREAM          =  4,  /* MDRawModuleList */
    317   MD_MEMORY_LIST_STREAM          =  5,  /* MDRawMemoryList */
    318   MD_EXCEPTION_STREAM            =  6,  /* MDRawExceptionStream */
    319   MD_SYSTEM_INFO_STREAM          =  7,  /* MDRawSystemInfo */
    320   MD_THREAD_EX_LIST_STREAM       =  8,
    321   MD_MEMORY_64_LIST_STREAM       =  9,
    322   MD_COMMENT_STREAM_A            = 10,
    323   MD_COMMENT_STREAM_W            = 11,
    324   MD_HANDLE_DATA_STREAM          = 12,
    325   MD_FUNCTION_TABLE_STREAM       = 13,
    326   MD_UNLOADED_MODULE_LIST_STREAM = 14,
    327   MD_MISC_INFO_STREAM            = 15,  /* MDRawMiscInfo */
    328   MD_MEMORY_INFO_LIST_STREAM     = 16,  /* MDRawMemoryInfoList */
    329   MD_THREAD_INFO_LIST_STREAM     = 17,
    330   MD_HANDLE_OPERATION_LIST_STREAM = 18,
    331   MD_LAST_RESERVED_STREAM        = 0x0000ffff,
    332 
    333   /* Breakpad extension types.  0x4767 = "Gg" */
    334   MD_BREAKPAD_INFO_STREAM        = 0x47670001,  /* MDRawBreakpadInfo  */
    335   MD_ASSERTION_INFO_STREAM       = 0x47670002,  /* MDRawAssertionInfo */
    336   /* These are additional minidump stream values which are specific to
    337    * the linux breakpad implementation. */
    338   MD_LINUX_CPU_INFO              = 0x47670003,  /* /proc/cpuinfo      */
    339   MD_LINUX_PROC_STATUS           = 0x47670004,  /* /proc/$x/status    */
    340   MD_LINUX_LSB_RELEASE           = 0x47670005,  /* /etc/lsb-release   */
    341   MD_LINUX_CMD_LINE              = 0x47670006,  /* /proc/$x/cmdline   */
    342   MD_LINUX_ENVIRON               = 0x47670007,  /* /proc/$x/environ   */
    343   MD_LINUX_AUXV                  = 0x47670008,  /* /proc/$x/auxv      */
    344   MD_LINUX_MAPS                  = 0x47670009,  /* /proc/$x/maps      */
    345   MD_LINUX_DSO_DEBUG             = 0x4767000A   /* MDRawDebug{32,64}  */
    346 } MDStreamType;  /* MINIDUMP_STREAM_TYPE */
    347 
    348 
    349 typedef struct {
    350   uint32_t length;     /* Length of buffer in bytes (not characters),
    351                         * excluding 0-terminator */
    352   uint16_t buffer[1];  /* UTF-16-encoded, 0-terminated */
    353 } MDString;  /* MINIDUMP_STRING */
    354 
    355 static const size_t MDString_minsize = offsetof(MDString, buffer[0]);
    356 
    357 
    358 typedef struct {
    359   uint32_t             thread_id;
    360   uint32_t             suspend_count;
    361   uint32_t             priority_class;
    362   uint32_t             priority;
    363   uint64_t             teb;             /* Thread environment block */
    364   MDMemoryDescriptor   stack;
    365   MDLocationDescriptor thread_context;  /* MDRawContext[CPU] */
    366 } MDRawThread;  /* MINIDUMP_THREAD */
    367 
    368 
    369 typedef struct {
    370   uint32_t    number_of_threads;
    371   MDRawThread threads[1];
    372 } MDRawThreadList;  /* MINIDUMP_THREAD_LIST */
    373 
    374 static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList,
    375                                                        threads[0]);
    376 
    377 
    378 typedef struct {
    379   uint64_t             base_of_image;
    380   uint32_t             size_of_image;
    381   uint32_t             checksum;         /* 0 if unknown */
    382   uint32_t             time_date_stamp;  /* time_t */
    383   MDRVA                module_name_rva;  /* MDString, pathname or filename */
    384   MDVSFixedFileInfo    version_info;
    385 
    386   /* The next field stores a CodeView record and is populated when a module's
    387    * debug information resides in a PDB file.  It identifies the PDB file. */
    388   MDLocationDescriptor cv_record;
    389 
    390   /* The next field is populated when a module's debug information resides
    391    * in a DBG file.  It identifies the DBG file.  This field is effectively
    392    * obsolete with modules built by recent toolchains. */
    393   MDLocationDescriptor misc_record;
    394 
    395   /* Alignment problem: reserved0 and reserved1 are defined by the platform
    396    * SDK as 64-bit quantities.  However, that results in a structure whose
    397    * alignment is unpredictable on different CPUs and ABIs.  If the ABI
    398    * specifies full alignment of 64-bit quantities in structures (as ppc
    399    * does), there will be padding between miscRecord and reserved0.  If
    400    * 64-bit quantities can be aligned on 32-bit boundaries (as on x86),
    401    * this padding will not exist.  (Note that the structure up to this point
    402    * contains 1 64-bit member followed by 21 32-bit members.)
    403    * As a workaround, reserved0 and reserved1 are instead defined here as
    404    * four 32-bit quantities.  This should be harmless, as there are
    405    * currently no known uses for these fields. */
    406   uint32_t             reserved0[2];
    407   uint32_t             reserved1[2];
    408 } MDRawModule;  /* MINIDUMP_MODULE */
    409 
    410 /* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to
    411  * be tail-padded out to a multiple of 64 bits under some ABIs (such as PPC).
    412  * This doesn't occur on systems that don't tail-pad in this manner.  Define
    413  * this macro to be the usable size of the MDRawModule struct, and use it in
    414  * place of sizeof(MDRawModule). */
    415 #define MD_MODULE_SIZE 108
    416 
    417 
    418 /* (MDRawModule).cv_record can reference MDCVInfoPDB20 or MDCVInfoPDB70.
    419  * Ref.: http://www.debuginfo.com/articles/debuginfomatch.html
    420  * MDCVInfoPDB70 is the expected structure type with recent toolchains. */
    421 
    422 typedef struct {
    423   uint32_t signature;
    424   uint32_t offset;     /* Offset to debug data (expect 0 in minidump) */
    425 } MDCVHeader;
    426 
    427 typedef struct {
    428   MDCVHeader cv_header;
    429   uint32_t   signature;         /* time_t debug information created */
    430   uint32_t   age;               /* revision of PDB file */
    431   uint8_t    pdb_file_name[1];  /* Pathname or filename of PDB file */
    432 } MDCVInfoPDB20;
    433 
    434 static const size_t MDCVInfoPDB20_minsize = offsetof(MDCVInfoPDB20,
    435                                                      pdb_file_name[0]);
    436 
    437 #define MD_CVINFOPDB20_SIGNATURE 0x3031424e  /* cvHeader.signature = '01BN' */
    438 
    439 typedef struct {
    440   uint32_t  cv_signature;
    441   MDGUID    signature;         /* GUID, identifies PDB file */
    442   uint32_t  age;               /* Identifies incremental changes to PDB file */
    443   uint8_t   pdb_file_name[1];  /* Pathname or filename of PDB file,
    444                                 * 0-terminated 8-bit character data (UTF-8?) */
    445 } MDCVInfoPDB70;
    446 
    447 static const size_t MDCVInfoPDB70_minsize = offsetof(MDCVInfoPDB70,
    448                                                      pdb_file_name[0]);
    449 
    450 #define MD_CVINFOPDB70_SIGNATURE 0x53445352  /* cvSignature = 'SDSR' */
    451 
    452 typedef struct {
    453   uint32_t data1[2];
    454   uint32_t data2;
    455   uint32_t data3;
    456   uint32_t data4;
    457   uint32_t data5[3];
    458   uint8_t  extra[2];
    459 } MDCVInfoELF;
    460 
    461 /* In addition to the two CodeView record formats above, used for linking
    462  * to external pdb files, it is possible for debugging data to be carried
    463  * directly in the CodeView record itself.  These signature values will
    464  * be found in the first 4 bytes of the CodeView record.  Additional values
    465  * not commonly experienced in the wild are given by "Microsoft Symbol and
    466  * Type Information", http://www.x86.org/ftp/manuals/tools/sym.pdf, section
    467  * 7.2.  An in-depth description of the CodeView 4.1 format is given by
    468  * "Undocumented Windows 2000 Secrets", Windows 2000 Debugging Support/
    469  * Microsoft Symbol File Internals/CodeView Subsections,
    470  * http://www.rawol.com/features/undocumented/sbs-w2k-1-windows-2000-debugging-support.pdf
    471  */
    472 #define MD_CVINFOCV41_SIGNATURE 0x3930424e  /* '90BN', CodeView 4.10. */
    473 #define MD_CVINFOCV50_SIGNATURE 0x3131424e  /* '11BN', CodeView 5.0,
    474                                              * MS C7-format (/Z7). */
    475 
    476 #define MD_CVINFOUNKNOWN_SIGNATURE 0xffffffff  /* An unlikely value. */
    477 
    478 /* (MDRawModule).miscRecord can reference MDImageDebugMisc.  The Windows
    479  * structure is actually defined in WinNT.h.  This structure is effectively
    480  * obsolete with modules built by recent toolchains. */
    481 
    482 typedef struct {
    483   uint32_t  data_type;    /* IMAGE_DEBUG_TYPE_*, not defined here because
    484                            * this debug record type is mostly obsolete. */
    485   uint32_t  length;       /* Length of entire MDImageDebugMisc structure */
    486   uint8_t   unicode;      /* True if data is multibyte */
    487   uint8_t   reserved[3];
    488   uint8_t   data[1];
    489 } MDImageDebugMisc;  /* IMAGE_DEBUG_MISC */
    490 
    491 static const size_t MDImageDebugMisc_minsize = offsetof(MDImageDebugMisc,
    492                                                         data[0]);
    493 
    494 
    495 typedef struct {
    496   uint32_t    number_of_modules;
    497   MDRawModule modules[1];
    498 } MDRawModuleList;  /* MINIDUMP_MODULE_LIST */
    499 
    500 static const size_t MDRawModuleList_minsize = offsetof(MDRawModuleList,
    501                                                        modules[0]);
    502 
    503 
    504 typedef struct {
    505   uint32_t           number_of_memory_ranges;
    506   MDMemoryDescriptor memory_ranges[1];
    507 } MDRawMemoryList;  /* MINIDUMP_MEMORY_LIST */
    508 
    509 static const size_t MDRawMemoryList_minsize = offsetof(MDRawMemoryList,
    510                                                        memory_ranges[0]);
    511 
    512 
    513 #define MD_EXCEPTION_MAXIMUM_PARAMETERS 15
    514 
    515 typedef struct {
    516   uint32_t  exception_code;     /* Windows: MDExceptionCodeWin,
    517                                  * Mac OS X: MDExceptionMac,
    518                                  * Linux: MDExceptionCodeLinux. */
    519   uint32_t  exception_flags;    /* Windows: 1 if noncontinuable,
    520                                    Mac OS X: MDExceptionCodeMac. */
    521   uint64_t  exception_record;   /* Address (in the minidump-producing host's
    522                                  * memory) of another MDException, for
    523                                  * nested exceptions. */
    524   uint64_t  exception_address;  /* The address that caused the exception.
    525                                  * Mac OS X: exception subcode (which is
    526                                  *           typically the address). */
    527   uint32_t  number_parameters;  /* Number of valid elements in
    528                                  * exception_information. */
    529   uint32_t  __align;
    530   uint64_t  exception_information[MD_EXCEPTION_MAXIMUM_PARAMETERS];
    531 } MDException;  /* MINIDUMP_EXCEPTION */
    532 
    533 #include "minidump_exception_linux.h"
    534 #include "minidump_exception_mac.h"
    535 #include "minidump_exception_ps3.h"
    536 #include "minidump_exception_solaris.h"
    537 #include "minidump_exception_win32.h"
    538 
    539 typedef struct {
    540   uint32_t             thread_id;         /* Thread in which the exception
    541                                            * occurred.  Corresponds to
    542                                            * (MDRawThread).thread_id. */
    543   uint32_t             __align;
    544   MDException          exception_record;
    545   MDLocationDescriptor thread_context;    /* MDRawContext[CPU] */
    546 } MDRawExceptionStream;  /* MINIDUMP_EXCEPTION_STREAM */
    547 
    548 
    549 typedef union {
    550   struct {
    551     uint32_t vendor_id[3];               /* cpuid 0: ebx, edx, ecx */
    552     uint32_t version_information;        /* cpuid 1: eax */
    553     uint32_t feature_information;        /* cpuid 1: edx */
    554     uint32_t amd_extended_cpu_features;  /* cpuid 0x80000001, ebx */
    555   } x86_cpu_info;
    556   struct {
    557     uint32_t cpuid;
    558     uint32_t elf_hwcaps;    /* linux specific, 0 otherwise */
    559   } arm_cpu_info;
    560   struct {
    561     uint64_t processor_features[2];
    562   } other_cpu_info;
    563 } MDCPUInformation;  /* CPU_INFORMATION */
    564 
    565 /* For (MDCPUInformation).arm_cpu_info.elf_hwcaps.
    566  * This matches the Linux kernel definitions from <asm/hwcaps.h> */
    567 typedef enum {
    568   MD_CPU_ARM_ELF_HWCAP_SWP       = (1 << 0),
    569   MD_CPU_ARM_ELF_HWCAP_HALF      = (1 << 1),
    570   MD_CPU_ARM_ELF_HWCAP_THUMB     = (1 << 2),
    571   MD_CPU_ARM_ELF_HWCAP_26BIT     = (1 << 3),
    572   MD_CPU_ARM_ELF_HWCAP_FAST_MULT = (1 << 4),
    573   MD_CPU_ARM_ELF_HWCAP_FPA       = (1 << 5),
    574   MD_CPU_ARM_ELF_HWCAP_VFP       = (1 << 6),
    575   MD_CPU_ARM_ELF_HWCAP_EDSP      = (1 << 7),
    576   MD_CPU_ARM_ELF_HWCAP_JAVA      = (1 << 8),
    577   MD_CPU_ARM_ELF_HWCAP_IWMMXT    = (1 << 9),
    578   MD_CPU_ARM_ELF_HWCAP_CRUNCH    = (1 << 10),
    579   MD_CPU_ARM_ELF_HWCAP_THUMBEE   = (1 << 11),
    580   MD_CPU_ARM_ELF_HWCAP_NEON      = (1 << 12),
    581   MD_CPU_ARM_ELF_HWCAP_VFPv3     = (1 << 13),
    582   MD_CPU_ARM_ELF_HWCAP_VFPv3D16  = (1 << 14),
    583   MD_CPU_ARM_ELF_HWCAP_TLS       = (1 << 15),
    584   MD_CPU_ARM_ELF_HWCAP_VFPv4     = (1 << 16),
    585   MD_CPU_ARM_ELF_HWCAP_IDIVA     = (1 << 17),
    586   MD_CPU_ARM_ELF_HWCAP_IDIVT     = (1 << 18),
    587 } MDCPUInformationARMElfHwCaps;
    588 
    589 typedef struct {
    590   /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO
    591    * structure as returned by GetSystemInfo */
    592   uint16_t         processor_architecture;
    593   uint16_t         processor_level;         /* x86: 5 = 586, 6 = 686, ... */
    594                                             /* ARM: 6 = ARMv6, 7 = ARMv7 ... */
    595   uint16_t         processor_revision;      /* x86: 0xMMSS, where MM=model,
    596                                              *      SS=stepping */
    597                                             /* ARM: 0 */
    598 
    599   uint8_t          number_of_processors;
    600   uint8_t          product_type;            /* Windows: VER_NT_* from WinNT.h */
    601 
    602   /* The next 5 fields are from the OSVERSIONINFO structure as returned
    603    * by GetVersionEx */
    604   uint32_t         major_version;
    605   uint32_t         minor_version;
    606   uint32_t         build_number;
    607   uint32_t         platform_id;
    608   MDRVA            csd_version_rva;  /* MDString further identifying the
    609                                       * host OS.
    610                                       * Windows: name of the installed OS
    611                                       *          service pack.
    612                                       * Mac OS X: the Apple OS build number
    613                                       *           (sw_vers -buildVersion).
    614                                       * Linux: uname -srvmo */
    615 
    616   uint16_t         suite_mask;       /* Windows: VER_SUITE_* from WinNT.h */
    617   uint16_t         reserved2;
    618 
    619   MDCPUInformation cpu;
    620 } MDRawSystemInfo;  /* MINIDUMP_SYSTEM_INFO */
    621 
    622 /* For (MDRawSystemInfo).processor_architecture: */
    623 typedef enum {
    624   MD_CPU_ARCHITECTURE_X86       =  0,  /* PROCESSOR_ARCHITECTURE_INTEL */
    625   MD_CPU_ARCHITECTURE_MIPS      =  1,  /* PROCESSOR_ARCHITECTURE_MIPS */
    626   MD_CPU_ARCHITECTURE_ALPHA     =  2,  /* PROCESSOR_ARCHITECTURE_ALPHA */
    627   MD_CPU_ARCHITECTURE_PPC       =  3,  /* PROCESSOR_ARCHITECTURE_PPC */
    628   MD_CPU_ARCHITECTURE_SHX       =  4,  /* PROCESSOR_ARCHITECTURE_SHX
    629                                         * (Super-H) */
    630   MD_CPU_ARCHITECTURE_ARM       =  5,  /* PROCESSOR_ARCHITECTURE_ARM */
    631   MD_CPU_ARCHITECTURE_IA64      =  6,  /* PROCESSOR_ARCHITECTURE_IA64 */
    632   MD_CPU_ARCHITECTURE_ALPHA64   =  7,  /* PROCESSOR_ARCHITECTURE_ALPHA64 */
    633   MD_CPU_ARCHITECTURE_MSIL      =  8,  /* PROCESSOR_ARCHITECTURE_MSIL
    634                                         * (Microsoft Intermediate Language) */
    635   MD_CPU_ARCHITECTURE_AMD64     =  9,  /* PROCESSOR_ARCHITECTURE_AMD64 */
    636   MD_CPU_ARCHITECTURE_X86_WIN64 = 10,
    637       /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
    638   MD_CPU_ARCHITECTURE_SPARC     = 0x8001, /* Breakpad-defined value for SPARC */
    639   MD_CPU_ARCHITECTURE_PPC64     = 0x8002, /* Breakpad-defined value for PPC64 */
    640   MD_CPU_ARCHITECTURE_ARM64     = 0x8003, /* Breakpad-defined value for ARM64 */
    641   MD_CPU_ARCHITECTURE_UNKNOWN   = 0xffff  /* PROCESSOR_ARCHITECTURE_UNKNOWN */
    642 } MDCPUArchitecture;
    643 
    644 /* For (MDRawSystemInfo).platform_id: */
    645 typedef enum {
    646   MD_OS_WIN32S        = 0,  /* VER_PLATFORM_WIN32s (Windows 3.1) */
    647   MD_OS_WIN32_WINDOWS = 1,  /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
    648   MD_OS_WIN32_NT      = 2,  /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
    649   MD_OS_WIN32_CE      = 3,  /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
    650                              * (Windows CE, Windows Mobile, "Handheld") */
    651 
    652   /* The following values are Breakpad-defined. */
    653   MD_OS_UNIX          = 0x8000,  /* Generic Unix-ish */
    654   MD_OS_MAC_OS_X      = 0x8101,  /* Mac OS X/Darwin */
    655   MD_OS_IOS           = 0x8102,  /* iOS */
    656   MD_OS_LINUX         = 0x8201,  /* Linux */
    657   MD_OS_SOLARIS       = 0x8202,  /* Solaris */
    658   MD_OS_ANDROID       = 0x8203,  /* Android */
    659   MD_OS_PS3           = 0x8204,  /* PS3 */
    660   MD_OS_NACL          = 0x8205   /* Native Client (NaCl) */
    661 } MDOSPlatform;
    662 
    663 typedef struct {
    664   uint16_t year;
    665   uint16_t month;
    666   uint16_t day_of_week;
    667   uint16_t day;
    668   uint16_t hour;
    669   uint16_t minute;
    670   uint16_t second;
    671   uint16_t milliseconds;
    672 } MDSystemTime;  /* SYSTEMTIME */
    673 
    674 typedef struct {
    675   /* Required field.  The bias is the difference, in minutes, between
    676    * Coordinated Universal Time (UTC) and local time.
    677    *   Formula: UTC = local time + bias */
    678   int32_t bias;
    679   /* A description for standard time.  For example, "EST" could indicate Eastern
    680    * Standard Time.  In practice this contains the full time zone names.  This
    681    * string can be empty. */
    682   uint16_t standard_name[32];  /* UTF-16-encoded, 0-terminated */
    683   /* A MDSystemTime structure that contains a date and local time when the
    684    * transition from daylight saving time to standard time occurs on this
    685    * operating system.  If the time zone does not support daylight saving time,
    686    * the month member in the MDSystemTime structure is zero. */
    687   MDSystemTime standard_date;
    688   /* The bias value to be used during local time translations that occur during
    689    * standard time. */
    690   int32_t standard_bias;
    691   /* A description for daylight saving time.  For example, "PDT" could indicate
    692    * Pacific Daylight Time.  In practice this contains the full time zone names.
    693    * This string can be empty. */
    694   uint16_t daylight_name[32];  /* UTF-16-encoded, 0-terminated */
    695   /* A MDSystemTime structure that contains a date and local time when the
    696    * transition from standard time to daylight saving time occurs on this
    697    * operating system.  If the time zone does not support daylight saving time,
    698    * the month member in the MDSystemTime structure is zero.*/
    699   MDSystemTime daylight_date;
    700   /* The bias value to be used during local time translations that occur during
    701    * daylight saving time. */
    702   int32_t daylight_bias;
    703 } MDTimeZoneInformation;  /* TIME_ZONE_INFORMATION */
    704 
    705 /* MAX_PATH from windef.h */
    706 #define MD_MAX_PATH 260
    707 
    708 /* The miscellaneous information stream contains a variety
    709  * of small pieces of information.  A member is valid if
    710  * it's within the available size and its corresponding
    711  * bit is set. */
    712 typedef struct {
    713   uint32_t size_of_info;  /* Length of entire MDRawMiscInfo structure. */
    714   uint32_t flags1;
    715 
    716   /* The next field is only valid if flags1 contains
    717    * MD_MISCINFO_FLAGS1_PROCESS_ID. */
    718   uint32_t process_id;
    719 
    720   /* The next 3 fields are only valid if flags1 contains
    721    * MD_MISCINFO_FLAGS1_PROCESS_TIMES. */
    722   uint32_t process_create_time;  /* time_t process started */
    723   uint32_t process_user_time;    /* seconds of user CPU time */
    724   uint32_t process_kernel_time;  /* seconds of kernel CPU time */
    725 
    726   /* The following fields are not present in MINIDUMP_MISC_INFO but are
    727    * in MINIDUMP_MISC_INFO_2.  When this struct is populated, these values
    728    * may not be set.  Use flags1 and size_of_info to determine whether these
    729    * values are present.  These are only valid when flags1 contains
    730    * MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
    731   uint32_t processor_max_mhz;
    732   uint32_t processor_current_mhz;
    733   uint32_t processor_mhz_limit;
    734   uint32_t processor_max_idle_state;
    735   uint32_t processor_current_idle_state;
    736 
    737   /* The following fields are not present in MINIDUMP_MISC_INFO_2 but are
    738    * in MINIDUMP_MISC_INFO_3.  When this struct is populated, these values
    739    * may not be set.  Use flags1 and size_of_info to determine whether these
    740    * values are present. */
    741 
    742   /* The following field is only valid if flags1 contains
    743    * MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY. */
    744   uint32_t process_integrity_level;
    745 
    746   /* The following field is only valid if flags1 contains
    747    * MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS. */
    748   uint32_t process_execute_flags;
    749 
    750   /* The following field is only valid if flags1 contains
    751    * MD_MISCINFO_FLAGS1_PROTECTED_PROCESS. */
    752   uint32_t protected_process;
    753 
    754   /* The following 2 fields are only valid if flags1 contains
    755    * MD_MISCINFO_FLAGS1_TIMEZONE. */
    756   uint32_t time_zone_id;
    757   MDTimeZoneInformation time_zone;
    758 
    759   /* The following fields are not present in MINIDUMP_MISC_INFO_3 but are
    760    * in MINIDUMP_MISC_INFO_4.  When this struct is populated, these values
    761    * may not be set.  Use flags1 and size_of_info to determine whether these
    762    * values are present. */
    763 
    764   /* The following 2 fields are only valid if flags1 contains
    765    * MD_MISCINFO_FLAGS1_BUILDSTRING. */
    766   uint16_t build_string[MD_MAX_PATH];  /* UTF-16-encoded, 0-terminated */
    767   uint16_t dbg_bld_str[40];            /* UTF-16-encoded, 0-terminated */
    768 } MDRawMiscInfo;  /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
    769                    * MINIDUMP_MISC_INFO_3, MINIDUMP_MISC_INFO_4,
    770                    * MINIDUMP_MISC_INFO_N */
    771 
    772 static const size_t MD_MISCINFO_SIZE =
    773     offsetof(MDRawMiscInfo, processor_max_mhz);
    774 static const size_t MD_MISCINFO2_SIZE =
    775     offsetof(MDRawMiscInfo, process_integrity_level);
    776 static const size_t MD_MISCINFO3_SIZE =
    777     offsetof(MDRawMiscInfo, build_string[0]);
    778 static const size_t MD_MISCINFO4_SIZE = sizeof(MDRawMiscInfo);
    779 
    780 /* For (MDRawMiscInfo).flags1.  These values indicate which fields in the
    781  * MDRawMiscInfoStructure are valid. */
    782 typedef enum {
    783   MD_MISCINFO_FLAGS1_PROCESS_ID            = 0x00000001,
    784       /* MINIDUMP_MISC1_PROCESS_ID */
    785   MD_MISCINFO_FLAGS1_PROCESS_TIMES         = 0x00000002,
    786       /* MINIDUMP_MISC1_PROCESS_TIMES */
    787   MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO  = 0x00000004,
    788       /* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
    789   MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY     = 0x00000010,
    790       /* MINIDUMP_MISC3_PROCESS_INTEGRITY */
    791   MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS = 0x00000020,
    792       /* MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS */
    793   MD_MISCINFO_FLAGS1_TIMEZONE              = 0x00000040,
    794       /* MINIDUMP_MISC3_TIMEZONE */
    795   MD_MISCINFO_FLAGS1_PROTECTED_PROCESS     = 0x00000080,
    796       /* MINIDUMP_MISC3_PROTECTED_PROCESS */
    797   MD_MISCINFO_FLAGS1_BUILDSTRING           = 0x00000100,
    798       /* MINIDUMP_MISC4_BUILDSTRING */
    799 } MDMiscInfoFlags1;
    800 
    801 /*
    802  * Around DbgHelp version 6.0, the style of new LIST structures changed
    803  * from including an array of length 1 at the end of the struct to
    804  * represent the variable-length data to including explicit
    805  * "size of header", "size of entry" and "number of entries" fields
    806  * in the header, presumably to allow backwards-compatibly-extending
    807  * the structures in the future. The actual list entries follow the
    808  * header data directly in this case.
    809  */
    810 
    811 typedef struct {
    812   uint32_t size_of_header;    /* sizeof(MDRawMemoryInfoList) */
    813   uint32_t size_of_entry;     /* sizeof(MDRawMemoryInfo) */
    814   uint64_t number_of_entries;
    815 } MDRawMemoryInfoList;  /* MINIDUMP_MEMORY_INFO_LIST */
    816 
    817 typedef struct {
    818   uint64_t  base_address;           /* Base address of a region of pages */
    819   uint64_t  allocation_base;        /* Base address of a range of pages
    820                                      * within this region. */
    821   uint32_t  allocation_protection;  /* Memory protection when this region
    822                                      * was originally allocated:
    823                                      * MDMemoryProtection */
    824   uint32_t  __alignment1;
    825   uint64_t  region_size;
    826   uint32_t  state;                  /* MDMemoryState */
    827   uint32_t  protection;             /* MDMemoryProtection */
    828   uint32_t  type;                   /* MDMemoryType */
    829   uint32_t  __alignment2;
    830 } MDRawMemoryInfo;  /* MINIDUMP_MEMORY_INFO */
    831 
    832 /* For (MDRawMemoryInfo).state */
    833 typedef enum {
    834   MD_MEMORY_STATE_COMMIT   = 0x1000,  /* physical storage has been allocated */
    835   MD_MEMORY_STATE_RESERVE  = 0x2000,  /* reserved, but no physical storage */
    836   MD_MEMORY_STATE_FREE     = 0x10000  /* available to be allocated */
    837 } MDMemoryState;
    838 
    839 /* For (MDRawMemoryInfo).allocation_protection and .protection */
    840 typedef enum {
    841   MD_MEMORY_PROTECT_NOACCESS          = 0x01,  /* PAGE_NOACCESS */
    842   MD_MEMORY_PROTECT_READONLY          = 0x02,  /* PAGE_READONLY */
    843   MD_MEMORY_PROTECT_READWRITE         = 0x04,  /* PAGE_READWRITE */
    844   MD_MEMORY_PROTECT_WRITECOPY         = 0x08,  /* PAGE_WRITECOPY */
    845   MD_MEMORY_PROTECT_EXECUTE           = 0x10,  /* PAGE_EXECUTE */
    846   MD_MEMORY_PROTECT_EXECUTE_READ      = 0x20,  /* PAGE_EXECUTE_READ */
    847   MD_MEMORY_PROTECT_EXECUTE_READWRITE = 0x40,  /* PAGE_EXECUTE_READWRITE */
    848   MD_MEMORY_PROTECT_EXECUTE_WRITECOPY = 0x80,  /* PAGE_EXECUTE_WRITECOPY */
    849   /* These options can be combined with the previous flags. */
    850   MD_MEMORY_PROTECT_GUARD             = 0x100,  /* PAGE_GUARD */
    851   MD_MEMORY_PROTECT_NOCACHE           = 0x200,  /* PAGE_NOCACHE */
    852   MD_MEMORY_PROTECT_WRITECOMBINE      = 0x400,  /* PAGE_WRITECOMBINE */
    853 } MDMemoryProtection;
    854 
    855 /* Used to mask the mutually exclusive options from the combinable flags. */
    856 const uint32_t MD_MEMORY_PROTECTION_ACCESS_MASK = 0xFF;
    857 
    858 /* For (MDRawMemoryInfo).type */
    859 typedef enum {
    860   MD_MEMORY_TYPE_PRIVATE = 0x20000,   /* not shared by other processes */
    861   MD_MEMORY_TYPE_MAPPED  = 0x40000,   /* mapped into the view of a section */
    862   MD_MEMORY_TYPE_IMAGE   = 0x1000000  /* mapped into the view of an image */
    863 } MDMemoryType;
    864 
    865 /*
    866  * Breakpad extension types
    867  */
    868 
    869 
    870 typedef struct {
    871   /* validity is a bitmask with values from MDBreakpadInfoValidity, indicating
    872    * which of the other fields in the structure are valid. */
    873   uint32_t validity;
    874 
    875   /* Thread ID of the handler thread.  dump_thread_id should correspond to
    876    * the thread_id of an MDRawThread in the minidump's MDRawThreadList if
    877    * a dedicated thread in that list was used to produce the minidump.  If
    878    * the MDRawThreadList does not contain a dedicated thread used to produce
    879    * the minidump, this field should be set to 0 and the validity field
    880    * must not contain MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID. */
    881   uint32_t dump_thread_id;
    882 
    883   /* Thread ID of the thread that requested the minidump be produced.  As
    884    * with dump_thread_id, requesting_thread_id should correspond to the
    885    * thread_id of an MDRawThread in the minidump's MDRawThreadList.  For
    886    * minidumps produced as a result of an exception, requesting_thread_id
    887    * will be the same as the MDRawExceptionStream's thread_id field.  For
    888    * minidumps produced "manually" at the program's request,
    889    * requesting_thread_id will indicate which thread caused the dump to be
    890    * written.  If the minidump was produced at the request of something
    891    * other than a thread in the MDRawThreadList, this field should be set
    892    * to 0 and the validity field must not contain
    893    * MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID. */
    894   uint32_t requesting_thread_id;
    895 } MDRawBreakpadInfo;
    896 
    897 /* For (MDRawBreakpadInfo).validity: */
    898 typedef enum {
    899   /* When set, the dump_thread_id field is valid. */
    900   MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID       = 1 << 0,
    901 
    902   /* When set, the requesting_thread_id field is valid. */
    903   MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID = 1 << 1
    904 } MDBreakpadInfoValidity;
    905 
    906 typedef struct {
    907   /* expression, function, and file are 0-terminated UTF-16 strings.  They
    908    * may be truncated if necessary, but should always be 0-terminated when
    909    * written to a file.
    910    * Fixed-length strings are used because MiniDumpWriteDump doesn't offer
    911    * a way for user streams to point to arbitrary RVAs for strings. */
    912   uint16_t expression[128];  /* Assertion that failed... */
    913   uint16_t function[128];    /* ...within this function... */
    914   uint16_t file[128];        /* ...in this file... */
    915   uint32_t line;             /* ...at this line. */
    916   uint32_t type;
    917 } MDRawAssertionInfo;
    918 
    919 /* For (MDRawAssertionInfo).type: */
    920 typedef enum {
    921   MD_ASSERTION_INFO_TYPE_UNKNOWN = 0,
    922 
    923   /* Used for assertions that would be raised by the MSVC CRT but are
    924    * directed to an invalid parameter handler instead. */
    925   MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER,
    926 
    927   /* Used for assertions that would be raised by the MSVC CRT but are
    928    * directed to a pure virtual call handler instead. */
    929   MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL
    930 } MDAssertionInfoData;
    931 
    932 /* These structs are used to store the DSO debug data in Linux minidumps,
    933  * which is necessary for converting minidumps to usable coredumps.
    934  * Because of a historical accident, several fields are variably encoded
    935  * according to client word size, so tools potentially need to support both. */
    936 
    937 typedef struct {
    938   uint32_t  addr;
    939   MDRVA     name;
    940   uint32_t  ld;
    941 } MDRawLinkMap32;
    942 
    943 typedef struct {
    944   uint32_t  version;
    945   MDRVA     map;  /* array of MDRawLinkMap32 */
    946   uint32_t  dso_count;
    947   uint32_t  brk;
    948   uint32_t  ldbase;
    949   uint32_t  dynamic;
    950 } MDRawDebug32;
    951 
    952 typedef struct {
    953   uint64_t  addr;
    954   MDRVA     name;
    955   uint64_t  ld;
    956 } MDRawLinkMap64;
    957 
    958 typedef struct {
    959   uint32_t  version;
    960   MDRVA     map;  /* array of MDRawLinkMap64 */
    961   uint32_t  dso_count;
    962   uint64_t  brk;
    963   uint64_t  ldbase;
    964   uint64_t  dynamic;
    965 } MDRawDebug64;
    966 
    967 #if defined(_MSC_VER)
    968 #pragma warning(pop)
    969 #endif  /* _MSC_VER */
    970 
    971 
    972 #endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_FORMAT_H__ */
    973