1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_
16 #define CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_
17 
18 #include <windows.h>
19 #include <dbghelp.h>
20 #include <stdint.h>
21 #include <winnt.h>
22 
23 #include "base/compiler_specific.h"
24 #include "build/build_config.h"
25 #include "util/misc/pdb_structures.h"
26 #include "util/misc/uuid.h"
27 
28 #if defined(COMPILER_MSVC)
29 // C4200 is "nonstandard extension used : zero-sized array in struct/union".
30 // We would like to globally disable this warning, but unfortunately, the
31 // compiler is buggy and only supports disabling it with a pragma, so we can't
32 // disable it with other silly warnings in the build files. See:
33 //   https://connect.microsoft.com/VisualStudio/feedback/details/1114440
34 #pragma warning(push)
35 #pragma warning(disable: 4200)
36 
37 #define PACKED
38 #pragma pack(push, 1)
39 #else
40 #define PACKED __attribute__((packed))
41 #endif  // COMPILER_MSVC
42 
43 namespace crashpad {
44 
45 //! \brief Minidump stream type values for MINIDUMP_DIRECTORY::StreamType. Each
46 //!     stream structure has a corresponding stream type value to identify it.
47 //!
48 //! \sa MINIDUMP_STREAM_TYPE
49 enum MinidumpStreamType : uint32_t {
50   //! \brief The stream type for MINIDUMP_THREAD_LIST.
51   //!
52   //! \sa ThreadListStream
53   kMinidumpStreamTypeThreadList = ThreadListStream,
54 
55   //! \brief The stream type for MINIDUMP_MODULE_LIST.
56   //!
57   //! \sa ModuleListStream
58   kMinidumpStreamTypeModuleList = ModuleListStream,
59 
60   //! \brief The stream type for MINIDUMP_MEMORY_LIST.
61   //!
62   //! \sa MemoryListStream
63   kMinidumpStreamTypeMemoryList = MemoryListStream,
64 
65   //! \brief The stream type for MINIDUMP_EXCEPTION_STREAM.
66   //!
67   //! \sa ExceptionStream
68   kMinidumpStreamTypeException = ExceptionStream,
69 
70   //! \brief The stream type for MINIDUMP_SYSTEM_INFO.
71   //!
72   //! \sa SystemInfoStream
73   kMinidumpStreamTypeSystemInfo = SystemInfoStream,
74 
75   //! \brief The stream type for MINIDUMP_HANDLE_DATA_STREAM.
76   //!
77   //! \sa HandleDataStream
78   kMinidumpStreamTypeHandleData = HandleDataStream,
79 
80   //! \brief The stream type for MINIDUMP_UNLOADED_MODULE_LIST.
81   //!
82   //! \sa UnloadedModuleListStream
83   kMinidumpStreamTypeUnloadedModuleList = UnloadedModuleListStream,
84 
85   //! \brief The stream type for MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
86   //!     MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4.
87   //!
88   //! \sa MiscInfoStream
89   kMinidumpStreamTypeMiscInfo = MiscInfoStream,
90 
91   //! \brief The stream type for MINIDUMP_MEMORY_INFO_LIST.
92   //!
93   //! \sa MemoryInfoListStream
94   kMinidumpStreamTypeMemoryInfoList = MemoryInfoListStream,
95 
96   //! \brief The last reserved minidump stream.
97   //!
98   //! \sa MemoryInfoListStream
99   kMinidumpStreamTypeLastReservedStream = LastReservedStream,
100 
101   // 0x4350 = "CP"
102 
103   //! \brief The stream type for MinidumpCrashpadInfo.
104   kMinidumpStreamTypeCrashpadInfo = 0x43500001,
105 
106   //! \brief The last reserved crashpad stream.
107   kMinidumpStreamTypeCrashpadLastReservedStream = 0x4350ffff,
108 };
109 
110 //! \brief A variable-length UTF-8-encoded string carried within a minidump
111 //!     file.
112 //!
113 //! \sa MINIDUMP_STRING
114 struct ALIGNAS(4) PACKED MinidumpUTF8String {
115   // The field names do not conform to typical style, they match the names used
116   // in MINIDUMP_STRING. This makes it easier to operate on MINIDUMP_STRING (for
117   // UTF-16 strings) and MinidumpUTF8String using templates.
118 
119   //! \brief The length of the #Buffer field in bytes, not including the `NUL`
120   //!     terminator.
121   //!
122   //! \note This field is interpreted as a byte count, not a count of Unicode
123   //!     code points.
124   uint32_t Length;
125 
126   //! \brief The string, encoded in UTF-8, and terminated with a `NUL` byte.
127   uint8_t Buffer[0];
128 };
129 
130 //! \brief A variable-length array of bytes carried within a minidump file.
131 //!     The data have no intrinsic type and should be interpreted according
132 //!     to their referencing context.
133 struct ALIGNAS(4) PACKED MinidumpByteArray {
134   //! \brief The length of the #data field.
135   uint32_t length;
136 
137   //! \brief The bytes of data.
138   uint8_t data[0];
139 };
140 
141 //! \brief CPU type values for MINIDUMP_SYSTEM_INFO::ProcessorArchitecture.
142 //!
143 //! \sa \ref PROCESSOR_ARCHITECTURE_x "PROCESSOR_ARCHITECTURE_*"
144 enum MinidumpCPUArchitecture : uint16_t {
145   //! \brief 32-bit x86.
146   //!
147   //! These systems identify their CPUs generically as “x86” or “ia32”, or with
148   //! more specific names such as “i386”, “i486”, “i586”, and “i686”.
149   kMinidumpCPUArchitectureX86 = PROCESSOR_ARCHITECTURE_INTEL,
150 
151   kMinidumpCPUArchitectureMIPS = PROCESSOR_ARCHITECTURE_MIPS,
152   kMinidumpCPUArchitectureAlpha = PROCESSOR_ARCHITECTURE_ALPHA,
153 
154   //! \brief 32-bit PowerPC.
155   //!
156   //! These systems identify their CPUs generically as “ppc”, or with more
157   //! specific names such as “ppc6xx”, “ppc7xx”, and “ppc74xx”.
158   kMinidumpCPUArchitecturePPC = PROCESSOR_ARCHITECTURE_PPC,
159 
160   kMinidumpCPUArchitectureSHx = PROCESSOR_ARCHITECTURE_SHX,
161 
162   //! \brief 32-bit ARM.
163   //!
164   //! These systems identify their CPUs generically as “arm”, or with more
165   //! specific names such as “armv6” and “armv7”.
166   kMinidumpCPUArchitectureARM = PROCESSOR_ARCHITECTURE_ARM,
167 
168   kMinidumpCPUArchitectureIA64 = PROCESSOR_ARCHITECTURE_IA64,
169   kMinidumpCPUArchitectureAlpha64 = PROCESSOR_ARCHITECTURE_ALPHA64,
170   kMinidumpCPUArchitectureMSIL = PROCESSOR_ARCHITECTURE_MSIL,
171 
172   //! \brief 64-bit x86.
173   //!
174   //! These systems identify their CPUs as “x86_64”, “amd64”, or “x64”.
175   kMinidumpCPUArchitectureAMD64 = PROCESSOR_ARCHITECTURE_AMD64,
176 
177   //! \brief A 32-bit x86 process running on IA-64 (Itanium).
178   //!
179   //! \note This value is not used in minidump files for 32-bit x86 processes
180   //!     running on a 64-bit-capable x86 CPU and operating system. In that
181   //!     configuration, #kMinidumpCPUArchitectureX86 is used instead.
182   kMinidumpCPUArchitectureX86Win64 = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64,
183 
184   kMinidumpCPUArchitectureNeutral = PROCESSOR_ARCHITECTURE_NEUTRAL,
185 
186   //! \brief 64-bit ARM.
187   //!
188   //! These systems identify their CPUs generically as “arm64” or “aarch64”, or
189   //! with more specific names such as “armv8”.
190   //!
191   //! \sa #kMinidumpCPUArchitectureARM64Breakpad
192   kMinidumpCPUArchitectureARM64 = PROCESSOR_ARCHITECTURE_ARM64,
193 
194   kMinidumpCPUArchitectureARM32Win64 = PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64,
195   kMinidumpCPUArchitectureSPARC = 0x8001,
196 
197   //! \brief 64-bit PowerPC.
198   //!
199   //! These systems identify their CPUs generically as “ppc64”, or with more
200   //! specific names such as “ppc970”.
201   kMinidumpCPUArchitecturePPC64 = 0x8002,
202 
203   //! \brief Used by Breakpad for 64-bit ARM.
204   //!
205   //! \deprecated Use #kMinidumpCPUArchitectureARM64 instead.
206   kMinidumpCPUArchitectureARM64Breakpad = 0x8003,
207 
208   //! \brief Unknown CPU architecture.
209   kMinidumpCPUArchitectureUnknown = PROCESSOR_ARCHITECTURE_UNKNOWN,
210 };
211 
212 //! \brief Operating system type values for MINIDUMP_SYSTEM_INFO::ProductType.
213 //!
214 //! \sa \ref VER_NT_x "VER_NT_*"
215 enum MinidumpOSType : uint8_t {
216   //! \brief A “desktop” or “workstation” system.
217   kMinidumpOSTypeWorkstation = VER_NT_WORKSTATION,
218 
219   //! \brief A “domain controller” system. Windows-specific.
220   kMinidumpOSTypeDomainController = VER_NT_DOMAIN_CONTROLLER,
221 
222   //! \brief A “server” system.
223   kMinidumpOSTypeServer = VER_NT_SERVER,
224 };
225 
226 //! \brief Operating system family values for MINIDUMP_SYSTEM_INFO::PlatformId.
227 //!
228 //! \sa \ref VER_PLATFORM_x "VER_PLATFORM_*"
229 enum MinidumpOS : uint32_t {
230   //! \brief Windows 3.1.
231   kMinidumpOSWin32s = VER_PLATFORM_WIN32s,
232 
233   //! \brief Windows 95, Windows 98, and Windows Me.
234   kMinidumpOSWin32Windows = VER_PLATFORM_WIN32_WINDOWS,
235 
236   //! \brief Windows NT, Windows 2000, and later.
237   kMinidumpOSWin32NT = VER_PLATFORM_WIN32_NT,
238 
239   kMinidumpOSUnix = 0x8000,
240 
241   //! \brief macOS, Darwin for traditional systems.
242   kMinidumpOSMacOSX = 0x8101,
243 
244   //! \brief iOS, Darwin for mobile devices.
245   kMinidumpOSIOS = 0x8102,
246 
247   //! \brief Linux, not including Android.
248   kMinidumpOSLinux = 0x8201,
249 
250   kMinidumpOSSolaris = 0x8202,
251 
252   //! \brief Android.
253   kMinidumpOSAndroid = 0x8203,
254 
255   kMinidumpOSPS3 = 0x8204,
256 
257   //! \brief Native Client (NaCl).
258   kMinidumpOSNaCl = 0x8205,
259 
260   //! \brief Fuchsia.
261   kMinidumpOSFuchsia = 0x8206,
262 
263   //! \brief Unknown operating system.
264   kMinidumpOSUnknown = 0xffffffff,
265 };
266 
267 //! \brief A list of ::RVA pointers.
268 struct ALIGNAS(4) PACKED MinidumpRVAList {
269   //! \brief The number of children present in the #children array.
270   uint32_t count;
271 
272   //! \brief Pointers to other structures in the minidump file.
273   RVA children[0];
274 };
275 
276 //! \brief A key-value pair.
277 struct ALIGNAS(4) PACKED MinidumpSimpleStringDictionaryEntry {
278   //! \brief ::RVA of a MinidumpUTF8String containing the key of a key-value
279   //!     pair.
280   RVA key;
281 
282   //! \brief ::RVA of a MinidumpUTF8String containing the value of a key-value
283   //!     pair.
284   RVA value;
285 };
286 
287 //! \brief A list of key-value pairs.
288 struct ALIGNAS(4) PACKED MinidumpSimpleStringDictionary {
289   //! \brief The number of key-value pairs present.
290   uint32_t count;
291 
292   //! \brief A list of MinidumpSimpleStringDictionaryEntry entries.
293   MinidumpSimpleStringDictionaryEntry entries[0];
294 };
295 
296 //! \brief A typed annotation object.
297 struct ALIGNAS(4) PACKED MinidumpAnnotation {
298   //! \brief ::RVA of a MinidumpUTF8String containing the name of the
299   //!     annotation.
300   RVA name;
301 
302   //! \brief The type of data stored in the \a value of the annotation. This
303   //!     may correspond to an \a Annotation::Type or it may be user-defined.
304   uint16_t type;
305 
306   //! \brief This field is always `0`.
307   uint16_t reserved;
308 
309   //! \brief ::RVA of a MinidumpByteArray to the data for the annotation.
310   RVA value;
311 };
312 
313 //! \brief A list of annotation objects.
314 struct ALIGNAS(4) PACKED MinidumpAnnotationList {
315   //! \brief The number of annotation objects present.
316   uint32_t count;
317 
318   //! \brief A list of MinidumpAnnotation objects.
319   MinidumpAnnotation objects[0];
320 };
321 
322 //! \brief Additional Crashpad-specific information about a module carried
323 //!     within a minidump file.
324 //!
325 //! This structure augments the information provided by MINIDUMP_MODULE. The
326 //! minidump file must contain a module list stream
327 //! (::kMinidumpStreamTypeModuleList) in order for this structure to appear.
328 //!
329 //! This structure is versioned. When changing this structure, leave the
330 //! existing structure intact so that earlier parsers will be able to understand
331 //! the fields they are aware of, and make additions at the end of the
332 //! structure. Revise #kVersion and document each field’s validity based on
333 //! #version, so that newer parsers will be able to determine whether the added
334 //! fields are valid or not.
335 //!
336 //! \sa MinidumpModuleCrashpadInfoList
337 struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfo {
338   //! \brief The structure’s currently-defined version number.
339   //!
340   //! \sa version
341   static constexpr uint32_t kVersion = 1;
342 
343   //! \brief The structure’s version number.
344   //!
345   //! Readers can use this field to determine which other fields in the
346   //! structure are valid. Upon encountering a value greater than #kVersion, a
347   //! reader should assume that the structure’s layout is compatible with the
348   //! structure defined as having value #kVersion.
349   //!
350   //! Writers may produce values less than #kVersion in this field if there is
351   //! no need for any fields present in later versions.
352   uint32_t version;
353 
354   //! \brief A MinidumpRVAList pointing to MinidumpUTF8String objects. The
355   //!     module controls the data that appears here.
356   //!
357   //! These strings correspond to ModuleSnapshot::AnnotationsVector() and do not
358   //! duplicate anything in #simple_annotations or #annotation_objects.
359   //!
360   //! This field is present when #version is at least `1`.
361   MINIDUMP_LOCATION_DESCRIPTOR list_annotations;
362 
363   //! \brief A MinidumpSimpleStringDictionary pointing to strings interpreted as
364   //!     key-value pairs. The module controls the data that appears here.
365   //!
366   //! These key-value pairs correspond to
367   //! ModuleSnapshot::AnnotationsSimpleMap() and do not duplicate anything in
368   //! #list_annotations or #annotation_objects.
369   //!
370   //! This field is present when #version is at least `1`.
371   MINIDUMP_LOCATION_DESCRIPTOR simple_annotations;
372 
373   //! \brief A MinidumpAnnotationList object containing the annotation objects
374   //!     stored within the module. The module controls the data that appears
375   //!     here.
376   //!
377   //! These key-value pairs correspond to ModuleSnapshot::AnnotationObjects()
378   //! and do not duplicate anything in #list_annotations or #simple_annotations.
379   //!
380   //! This field may be present when #version is at least `1`.
381   MINIDUMP_LOCATION_DESCRIPTOR annotation_objects;
382 };
383 
384 //! \brief A link between a MINIDUMP_MODULE structure and additional
385 //!     Crashpad-specific information about a module carried within a minidump
386 //!     file.
387 struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfoLink {
388   //! \brief A link to a MINIDUMP_MODULE structure in the module list stream.
389   //!
390   //! This field is an index into MINIDUMP_MODULE_LIST::Modules. This field’s
391   //! value must be in the range of MINIDUMP_MODULE_LIST::NumberOfEntries.
392   uint32_t minidump_module_list_index;
393 
394   //! \brief A link to a MinidumpModuleCrashpadInfo structure.
395   //!
396   //! MinidumpModuleCrashpadInfo structures are accessed indirectly through
397   //! MINIDUMP_LOCATION_DESCRIPTOR pointers to allow for future growth of the
398   //! MinidumpModuleCrashpadInfo structure.
399   MINIDUMP_LOCATION_DESCRIPTOR location;
400 };
401 
402 //! \brief Additional Crashpad-specific information about modules carried within
403 //!     a minidump file.
404 //!
405 //! This structure augments the information provided by
406 //! MINIDUMP_MODULE_LIST. The minidump file must contain a module list stream
407 //! (::kMinidumpStreamTypeModuleList) in order for this structure to appear.
408 //!
409 //! MinidumpModuleCrashpadInfoList::count may be less than the value of
410 //! MINIDUMP_MODULE_LIST::NumberOfModules because not every MINIDUMP_MODULE
411 //! structure carried within the minidump file will necessarily have
412 //! Crashpad-specific information provided by a MinidumpModuleCrashpadInfo
413 //! structure.
414 struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfoList {
415   //! \brief The number of children present in the #modules array.
416   uint32_t count;
417 
418   //! \brief Crashpad-specific information about modules, along with links to
419   //!     MINIDUMP_MODULE structures that contain module information
420   //!     traditionally carried within minidump files.
421   MinidumpModuleCrashpadInfoLink modules[0];
422 };
423 
424 //! \brief Additional Crashpad-specific information carried within a minidump
425 //!     file.
426 //!
427 //! This structure is versioned. When changing this structure, leave the
428 //! existing structure intact so that earlier parsers will be able to understand
429 //! the fields they are aware of, and make additions at the end of the
430 //! structure. Revise #kVersion and document each field’s validity based on
431 //! #version, so that newer parsers will be able to determine whether the added
432 //! fields are valid or not.
433 struct ALIGNAS(4) PACKED MinidumpCrashpadInfo {
434   // UUID has a constructor, which makes it non-POD, which makes this structure
435   // non-POD. In order for the default constructor to zero-initialize other
436   // members, an explicit constructor must be provided.
MinidumpCrashpadInfoMinidumpCrashpadInfo437   MinidumpCrashpadInfo()
438       : version(),
439         report_id(),
440         client_id(),
441         simple_annotations(),
442         module_list() {
443   }
444 
445   //! \brief The structure’s currently-defined version number.
446   //!
447   //! \sa version
448   static constexpr uint32_t kVersion = 1;
449 
450   //! \brief The structure’s version number.
451   //!
452   //! Readers can use this field to determine which other fields in the
453   //! structure are valid. Upon encountering a value greater than #kVersion, a
454   //! reader should assume that the structure’s layout is compatible with the
455   //! structure defined as having value #kVersion.
456   //!
457   //! Writers may produce values less than #kVersion in this field if there is
458   //! no need for any fields present in later versions.
459   uint32_t version;
460 
461   //! \brief A %UUID identifying an individual crash report.
462   //!
463   //! This provides a stable identifier for a crash even as the report is
464   //! converted to different formats, provided that all formats support storing
465   //! a crash report ID.
466   //!
467   //! If no identifier is available, this field will contain zeroes.
468   //!
469   //! This field is present when #version is at least `1`.
470   UUID report_id;
471 
472   //! \brief A %UUID identifying the client that crashed.
473   //!
474   //! Client identification is within the scope of the application, but it is
475   //! expected that the identifier will be unique for an instance of Crashpad
476   //! monitoring an application or set of applications for a user. The
477   //! identifier shall remain stable over time.
478   //!
479   //! If no identifier is available, this field will contain zeroes.
480   //!
481   //! This field is present when #version is at least `1`.
482   UUID client_id;
483 
484   //! \brief A MinidumpSimpleStringDictionary pointing to strings interpreted as
485   //!     key-value pairs.
486   //!
487   //! These key-value pairs correspond to
488   //! ProcessSnapshot::AnnotationsSimpleMap().
489   //!
490   //! This field is present when #version is at least `1`.
491   MINIDUMP_LOCATION_DESCRIPTOR simple_annotations;
492 
493   //! \brief A pointer to a MinidumpModuleCrashpadInfoList structure.
494   //!
495   //! This field is present when #version is at least `1`.
496   MINIDUMP_LOCATION_DESCRIPTOR module_list;
497 };
498 
499 #if defined(COMPILER_MSVC)
500 #pragma pack(pop)
501 #pragma warning(pop)  // C4200
502 #endif  // COMPILER_MSVC
503 #undef PACKED
504 
505 }  // namespace crashpad
506 
507 #endif  // CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_
508