1 //===-- MinidumpTypes.h -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_MinidumpTypes_h_
11 #define liblldb_MinidumpTypes_h_
15 // Other libraries and framework includes
16 #include "lldb/Utility/Status.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/BitmaskEnum.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/ConvertUTF.h"
24 #include "llvm/Support/Endian.h"
30 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms679293(v=vs.85).aspx
31 // https://chromium.googlesource.com/breakpad/breakpad/
33 namespace lldb_private {
37 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
39 enum class MinidumpHeaderConstants : uint32_t {
40 Signature = 0x504d444d, // 'PMDM'
41 Version = 0x0000a793, // 42899
42 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Signature)
46 enum class CvSignature : uint32_t {
47 Pdb70 = 0x53445352, // RSDS
48 ElfBuildId = 0x4270454c, // BpEL (Breakpad/Crashpad minidumps)
52 // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
53 struct CvRecordPdb70 {
55 llvm::support::ulittle32_t Age;
56 // char PDBFileName[];
58 static_assert(sizeof(CvRecordPdb70) == 20,
59 "sizeof CvRecordPdb70 is not correct!");
62 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx
63 enum class MinidumpStreamType : uint32_t {
78 UnloadedModuleList = 14,
82 HandleOperationList = 18,
85 SystemMemoryInfo = 21,
86 ProcessVMCounters = 22,
87 LastReserved = 0x0000ffff,
89 /* Breakpad extension types. 0x4767 = "Gg" */
90 BreakpadInfo = 0x47670001,
91 AssertionInfo = 0x47670002,
92 /* These are additional minidump stream values which are specific to
93 * the linux breakpad implementation. */
94 LinuxCPUInfo = 0x47670003, /* /proc/cpuinfo */
95 LinuxProcStatus = 0x47670004, /* /proc/$x/status */
96 LinuxLSBRelease = 0x47670005, /* /etc/lsb-release */
97 LinuxCMDLine = 0x47670006, /* /proc/$x/cmdline */
98 LinuxEnviron = 0x47670007, /* /proc/$x/environ */
99 LinuxAuxv = 0x47670008, /* /proc/$x/auxv */
100 LinuxMaps = 0x47670009, /* /proc/$x/maps */
101 LinuxDSODebug = 0x4767000A
104 // for MinidumpSystemInfo.processor_arch
105 enum class MinidumpCPUArchitecture : uint16_t {
106 X86 = 0, /* PROCESSOR_ARCHITECTURE_INTEL */
107 MIPS = 1, /* PROCESSOR_ARCHITECTURE_MIPS */
108 Alpha = 2, /* PROCESSOR_ARCHITECTURE_ALPHA */
109 PPC = 3, /* PROCESSOR_ARCHITECTURE_PPC */
110 SHX = 4, /* PROCESSOR_ARCHITECTURE_SHX (Super-H) */
111 ARM = 5, /* PROCESSOR_ARCHITECTURE_ARM */
112 IA64 = 6, /* PROCESSOR_ARCHITECTURE_IA64 */
113 Alpha64 = 7, /* PROCESSOR_ARCHITECTURE_ALPHA64 */
114 MSIL = 8, /* PROCESSOR_ARCHITECTURE_MSIL
115 * (Microsoft Intermediate Language) */
116 AMD64 = 9, /* PROCESSOR_ARCHITECTURE_AMD64 */
117 X86Win64 = 10, /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
118 SPARC = 0x8001, /* Breakpad-defined value for SPARC */
119 PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */
120 ARM64 = 0x8003, /* Breakpad-defined value for ARM64 */
121 MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */
122 Unknown = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */
125 // for MinidumpSystemInfo.platform_id
126 enum class MinidumpOSPlatform : uint32_t {
127 Win32S = 0, /* VER_PLATFORM_WIN32s (Windows 3.1) */
128 Win32Windows = 1, /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
129 Win32NT = 2, /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
130 Win32CE = 3, /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
131 * (Windows CE, Windows Mobile, "Handheld") */
133 /* The following values are Breakpad-defined. */
134 Unix = 0x8000, /* Generic Unix-ish */
135 MacOSX = 0x8101, /* Mac OS X/Darwin */
136 IOS = 0x8102, /* iOS */
137 Linux = 0x8201, /* Linux */
138 Solaris = 0x8202, /* Solaris */
139 Android = 0x8203, /* Android */
140 PS3 = 0x8204, /* PS3 */
141 NaCl = 0x8205 /* Native Client (NaCl) */
144 // For MinidumpCPUInfo.arm_cpu_info.elf_hwcaps.
145 // This matches the Linux kernel definitions from <asm/hwcaps.h>
146 enum class MinidumpPCPUInformationARMElfHwCaps : uint32_t {
161 VFPv3D16 = (1 << 14),
166 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IDIVT)
169 enum class MinidumpMiscInfoFlags : uint32_t {
170 ProcessID = (1 << 0),
171 ProcessTimes = (1 << 1),
172 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)
175 template <typename T>
176 Status consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) {
178 if (Buffer.size() < sizeof(T)) {
179 error.SetErrorString("Insufficient buffer!");
183 Object = reinterpret_cast<const T *>(Buffer.data());
184 Buffer = Buffer.drop_front(sizeof(T));
188 // parse a MinidumpString which is with UTF-16
190 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680395(v=vs.85).aspx
191 llvm::Optional<std::string> parseMinidumpString(llvm::ArrayRef<uint8_t> &data);
194 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680378(v=vs.85).aspx
195 struct MinidumpHeader {
196 llvm::support::ulittle32_t signature;
197 llvm::support::ulittle32_t
198 version; // The high 16 bits of version field are implementation specific
199 llvm::support::ulittle32_t streams_count;
200 llvm::support::ulittle32_t
201 stream_directory_rva; // offset of the stream directory
202 llvm::support::ulittle32_t checksum;
203 llvm::support::ulittle32_t time_date_stamp; // time_t format
204 llvm::support::ulittle64_t flags;
206 static const MinidumpHeader *Parse(llvm::ArrayRef<uint8_t> &data);
208 static_assert(sizeof(MinidumpHeader) == 32,
209 "sizeof MinidumpHeader is not correct!");
212 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680383.aspx
213 struct MinidumpLocationDescriptor {
214 llvm::support::ulittle32_t data_size;
215 llvm::support::ulittle32_t rva;
217 static_assert(sizeof(MinidumpLocationDescriptor) == 8,
218 "sizeof MinidumpLocationDescriptor is not correct!");
221 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680384(v=vs.85).aspx
222 struct MinidumpMemoryDescriptor {
223 llvm::support::ulittle64_t start_of_memory_range;
224 MinidumpLocationDescriptor memory;
226 static llvm::ArrayRef<MinidumpMemoryDescriptor>
227 ParseMemoryList(llvm::ArrayRef<uint8_t> &data);
229 static_assert(sizeof(MinidumpMemoryDescriptor) == 16,
230 "sizeof MinidumpMemoryDescriptor is not correct!");
232 struct MinidumpMemoryDescriptor64 {
233 llvm::support::ulittle64_t start_of_memory_range;
234 llvm::support::ulittle64_t data_size;
236 static std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
237 ParseMemory64List(llvm::ArrayRef<uint8_t> &data);
239 static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
240 "sizeof MinidumpMemoryDescriptor64 is not correct!");
243 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680365.aspx
244 struct MinidumpDirectory {
245 llvm::support::ulittle32_t stream_type;
246 MinidumpLocationDescriptor location;
248 static_assert(sizeof(MinidumpDirectory) == 12,
249 "sizeof MinidumpDirectory is not correct!");
252 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx
253 struct MinidumpMemoryInfoListHeader {
254 llvm::support::ulittle32_t size_of_header;
255 llvm::support::ulittle32_t size_of_entry;
256 llvm::support::ulittle64_t num_of_entries;
258 static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
259 "sizeof MinidumpMemoryInfoListHeader is not correct!");
262 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
263 struct MinidumpMemoryInfo {
264 llvm::support::ulittle64_t base_address;
265 llvm::support::ulittle64_t allocation_base;
266 llvm::support::ulittle32_t allocation_protect;
267 llvm::support::ulittle32_t alignment1;
268 llvm::support::ulittle64_t region_size;
269 llvm::support::ulittle32_t state;
270 llvm::support::ulittle32_t protect;
271 llvm::support::ulittle32_t type;
272 llvm::support::ulittle32_t alignment2;
274 static std::vector<const MinidumpMemoryInfo *>
275 ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
277 static_assert(sizeof(MinidumpMemoryInfo) == 48,
278 "sizeof MinidumpMemoryInfo is not correct!");
280 enum class MinidumpMemoryInfoState : uint32_t {
284 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
287 enum class MinidumpMemoryInfoType : uint32_t {
288 MemImage = 0x1000000,
290 MemPrivate = 0x20000,
291 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
295 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
296 enum class MinidumpMemoryProtectionContants : uint32_t {
298 PageExecuteRead = 0x20,
299 PageExecuteReadWrite = 0x40,
300 PageExecuteWriteCopy = 0x80,
303 PageReadWrite = 0x04,
304 PageWriteCopy = 0x08,
305 PageTargetsInvalid = 0x40000000,
306 PageTargetsNoUpdate = 0x40000000,
308 PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
310 PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
311 PageExecuteWriteCopy,
312 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
316 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx
317 struct MinidumpThread {
318 llvm::support::ulittle32_t thread_id;
319 llvm::support::ulittle32_t suspend_count;
320 llvm::support::ulittle32_t priority_class;
321 llvm::support::ulittle32_t priority;
322 llvm::support::ulittle64_t teb;
323 MinidumpMemoryDescriptor stack;
324 MinidumpLocationDescriptor thread_context;
326 static const MinidumpThread *Parse(llvm::ArrayRef<uint8_t> &data);
328 static llvm::ArrayRef<MinidumpThread>
329 ParseThreadList(llvm::ArrayRef<uint8_t> &data);
331 static_assert(sizeof(MinidumpThread) == 48,
332 "sizeof MinidumpThread is not correct!");
335 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
336 union MinidumpCPUInfo {
338 llvm::support::ulittle32_t vendor_id[3]; /* cpuid 0: ebx, edx, ecx */
339 llvm::support::ulittle32_t version_information; /* cpuid 1: eax */
340 llvm::support::ulittle32_t feature_information; /* cpuid 1: edx */
341 llvm::support::ulittle32_t
342 amd_extended_cpu_features; /* cpuid 0x80000001, ebx */
345 llvm::support::ulittle32_t cpuid;
346 llvm::support::ulittle32_t elf_hwcaps; /* linux specific, 0 otherwise */
349 llvm::support::ulittle64_t processor_features[2];
352 static_assert(sizeof(MinidumpCPUInfo) == 24,
353 "sizeof MinidumpCPUInfo is not correct!");
356 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
357 struct MinidumpSystemInfo {
358 llvm::support::ulittle16_t processor_arch;
359 llvm::support::ulittle16_t processor_level;
360 llvm::support::ulittle16_t processor_revision;
362 uint8_t number_of_processors;
363 uint8_t product_type;
365 llvm::support::ulittle32_t major_version;
366 llvm::support::ulittle32_t minor_version;
367 llvm::support::ulittle32_t build_number;
368 llvm::support::ulittle32_t platform_id;
369 llvm::support::ulittle32_t csd_version_rva;
371 llvm::support::ulittle16_t suit_mask;
372 llvm::support::ulittle16_t reserved2;
376 static const MinidumpSystemInfo *Parse(llvm::ArrayRef<uint8_t> &data);
378 static_assert(sizeof(MinidumpSystemInfo) == 56,
379 "sizeof MinidumpSystemInfo is not correct!");
381 // TODO misc2, misc3 ?
383 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
384 struct MinidumpMiscInfo {
385 llvm::support::ulittle32_t size;
386 // flags1 represents what info in the struct is valid
387 llvm::support::ulittle32_t flags1;
388 llvm::support::ulittle32_t process_id;
389 llvm::support::ulittle32_t process_create_time;
390 llvm::support::ulittle32_t process_user_time;
391 llvm::support::ulittle32_t process_kernel_time;
393 static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data);
395 llvm::Optional<lldb::pid_t> GetPid() const;
397 static_assert(sizeof(MinidumpMiscInfo) == 24,
398 "sizeof MinidumpMiscInfo is not correct!");
400 // The /proc/pid/status is saved as an ascii string in the file
401 class LinuxProcStatus {
403 llvm::StringRef proc_status;
406 static llvm::Optional<LinuxProcStatus> Parse(llvm::ArrayRef<uint8_t> &data);
408 lldb::pid_t GetPid() const;
411 LinuxProcStatus() = default;
414 // MinidumpModule stuff
415 struct MinidumpVSFixedFileInfo {
416 llvm::support::ulittle32_t signature;
417 llvm::support::ulittle32_t struct_version;
418 llvm::support::ulittle32_t file_version_hi;
419 llvm::support::ulittle32_t file_version_lo;
420 llvm::support::ulittle32_t product_version_hi;
421 llvm::support::ulittle32_t product_version_lo;
422 // file_flags_mask - identifies valid bits in fileFlags
423 llvm::support::ulittle32_t file_flags_mask;
424 llvm::support::ulittle32_t file_flags;
425 llvm::support::ulittle32_t file_os;
426 llvm::support::ulittle32_t file_type;
427 llvm::support::ulittle32_t file_subtype;
428 llvm::support::ulittle32_t file_date_hi;
429 llvm::support::ulittle32_t file_date_lo;
431 static_assert(sizeof(MinidumpVSFixedFileInfo) == 52,
432 "sizeof MinidumpVSFixedFileInfo is not correct!");
434 struct MinidumpModule {
435 llvm::support::ulittle64_t base_of_image;
436 llvm::support::ulittle32_t size_of_image;
437 llvm::support::ulittle32_t checksum;
438 llvm::support::ulittle32_t time_date_stamp;
439 llvm::support::ulittle32_t module_name_rva;
440 MinidumpVSFixedFileInfo version_info;
441 MinidumpLocationDescriptor CV_record;
442 MinidumpLocationDescriptor misc_record;
443 llvm::support::ulittle32_t reserved0[2];
444 llvm::support::ulittle32_t reserved1[2];
446 static const MinidumpModule *Parse(llvm::ArrayRef<uint8_t> &data);
448 static llvm::ArrayRef<MinidumpModule>
449 ParseModuleList(llvm::ArrayRef<uint8_t> &data);
451 static_assert(sizeof(MinidumpModule) == 108,
452 "sizeof MinidumpVSFixedFileInfo is not correct!");
455 struct MinidumpException {
457 ExceptonInfoMaxParams = 15,
458 DumpRequested = 0xFFFFFFFF,
461 llvm::support::ulittle32_t exception_code;
462 llvm::support::ulittle32_t exception_flags;
463 llvm::support::ulittle64_t exception_record;
464 llvm::support::ulittle64_t exception_address;
465 llvm::support::ulittle32_t number_parameters;
466 llvm::support::ulittle32_t unused_alignment;
467 llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams];
469 static_assert(sizeof(MinidumpException) == 152,
470 "sizeof MinidumpException is not correct!");
472 struct MinidumpExceptionStream {
473 llvm::support::ulittle32_t thread_id;
474 llvm::support::ulittle32_t alignment;
475 MinidumpException exception_record;
476 MinidumpLocationDescriptor thread_context;
478 static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
480 static_assert(sizeof(MinidumpExceptionStream) == 168,
481 "sizeof MinidumpExceptionStream is not correct!");
483 } // namespace minidump
484 } // namespace lldb_private
485 #endif // liblldb_MinidumpTypes_h_