]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / minidump / MinidumpTypes.h
1 //===-- MinidumpTypes.h -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef liblldb_MinidumpTypes_h_
11 #define liblldb_MinidumpTypes_h_
12
13 // Project includes
14
15 // Other libraries and framework includes
16 #include "lldb/Utility/Status.h"
17
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"
25
26 // C includes
27 // C++ includes
28
29 // Reference:
30 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms679293(v=vs.85).aspx
31 // https://chromium.googlesource.com/breakpad/breakpad/
32
33 namespace lldb_private {
34
35 namespace minidump {
36
37 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
38
39 enum class MinidumpHeaderConstants : uint32_t {
40   Signature = 0x504d444d, // 'PMDM'
41   Version = 0x0000a793,   // 42899
42   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Signature)
43
44 };
45
46 enum class CvSignature : uint32_t {
47   Pdb70 = 0x53445352, // RSDS
48   ElfBuildId = 0x4270454c, // BpEL (Breakpad/Crashpad minidumps)
49 };
50
51 // Reference:
52 // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
53 struct CvRecordPdb70 {
54   uint8_t Uuid[16];
55   llvm::support::ulittle32_t Age;
56   // char PDBFileName[];
57 };
58 static_assert(sizeof(CvRecordPdb70) == 20,
59               "sizeof CvRecordPdb70 is not correct!");
60
61 // Reference:
62 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx
63 enum class MinidumpStreamType : uint32_t {
64   Unused = 0,
65   Reserved0 = 1,
66   Reserved1 = 2,
67   ThreadList = 3,
68   ModuleList = 4,
69   MemoryList = 5,
70   Exception = 6,
71   SystemInfo = 7,
72   ThreadExList = 8,
73   Memory64List = 9,
74   CommentA = 10,
75   CommentW = 11,
76   HandleData = 12,
77   FunctionTable = 13,
78   UnloadedModuleList = 14,
79   MiscInfo = 15,
80   MemoryInfoList = 16,
81   ThreadInfoList = 17,
82   HandleOperationList = 18,
83   Token = 19,
84   JavascriptData = 20,
85   SystemMemoryInfo = 21,
86   ProcessVMCounters = 22,
87   LastReserved = 0x0000ffff,
88
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
102 };
103
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 */
123 };
124
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") */
132
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) */
142 };
143
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 {
147   SWP = (1 << 0),
148   Half = (1 << 1),
149   Thumb = (1 << 2),
150   _26BIT = (1 << 3),
151   FastMult = (1 << 4),
152   FPA = (1 << 5),
153   VFP = (1 << 6),
154   EDSP = (1 << 7),
155   Java = (1 << 8),
156   IWMMXT = (1 << 9),
157   Crunch = (1 << 10),
158   ThumbEE = (1 << 11),
159   Neon = (1 << 12),
160   VFPv3 = (1 << 13),
161   VFPv3D16 = (1 << 14),
162   TLS = (1 << 15),
163   VFPv4 = (1 << 16),
164   IDIVA = (1 << 17),
165   IDIVT = (1 << 18),
166   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IDIVT)
167 };
168
169 enum class MinidumpMiscInfoFlags : uint32_t {
170   ProcessID = (1 << 0),
171   ProcessTimes = (1 << 1),
172   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)
173 };
174
175 template <typename T>
176 Status consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) {
177   Status error;
178   if (Buffer.size() < sizeof(T)) {
179     error.SetErrorString("Insufficient buffer!");
180     return error;
181   }
182
183   Object = reinterpret_cast<const T *>(Buffer.data());
184   Buffer = Buffer.drop_front(sizeof(T));
185   return error;
186 }
187
188 // parse a MinidumpString which is with UTF-16
189 // Reference:
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);
192
193 // Reference:
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;
205
206   static const MinidumpHeader *Parse(llvm::ArrayRef<uint8_t> &data);
207 };
208 static_assert(sizeof(MinidumpHeader) == 32,
209               "sizeof MinidumpHeader is not correct!");
210
211 // Reference:
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;
216 };
217 static_assert(sizeof(MinidumpLocationDescriptor) == 8,
218               "sizeof MinidumpLocationDescriptor is not correct!");
219
220 // Reference:
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;
225
226   static llvm::ArrayRef<MinidumpMemoryDescriptor>
227   ParseMemoryList(llvm::ArrayRef<uint8_t> &data);
228 };
229 static_assert(sizeof(MinidumpMemoryDescriptor) == 16,
230               "sizeof MinidumpMemoryDescriptor is not correct!");
231
232 struct MinidumpMemoryDescriptor64 {
233   llvm::support::ulittle64_t start_of_memory_range;
234   llvm::support::ulittle64_t data_size;
235
236   static std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
237   ParseMemory64List(llvm::ArrayRef<uint8_t> &data);
238 };
239 static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
240               "sizeof MinidumpMemoryDescriptor64 is not correct!");
241
242 // Reference:
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;
247 };
248 static_assert(sizeof(MinidumpDirectory) == 12,
249               "sizeof MinidumpDirectory is not correct!");
250
251 // Reference:
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;
257 };
258 static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
259               "sizeof MinidumpMemoryInfoListHeader is not correct!");
260
261 // Reference:
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;
273
274   static std::vector<const MinidumpMemoryInfo *>
275   ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
276 };
277 static_assert(sizeof(MinidumpMemoryInfo) == 48,
278               "sizeof MinidumpMemoryInfo is not correct!");
279
280 enum class MinidumpMemoryInfoState : uint32_t {
281   MemCommit = 0x1000,
282   MemFree = 0x10000,
283   MemReserve = 0x2000,
284   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
285 };
286
287 enum class MinidumpMemoryInfoType : uint32_t {
288   MemImage = 0x1000000,
289   MemMapped = 0x40000,
290   MemPrivate = 0x20000,
291   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
292 };
293
294 // Reference:
295 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
296 enum class MinidumpMemoryProtectionContants : uint32_t {
297   PageExecute = 0x10,
298   PageExecuteRead = 0x20,
299   PageExecuteReadWrite = 0x40,
300   PageExecuteWriteCopy = 0x80,
301   PageNoAccess = 0x01,
302   PageReadOnly = 0x02,
303   PageReadWrite = 0x04,
304   PageWriteCopy = 0x08,
305   PageTargetsInvalid = 0x40000000,
306   PageTargetsNoUpdate = 0x40000000,
307
308   PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
309                  PageWriteCopy,
310   PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
311                    PageExecuteWriteCopy,
312   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
313 };
314
315 // Reference:
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;
325
326   static const MinidumpThread *Parse(llvm::ArrayRef<uint8_t> &data);
327
328   static llvm::ArrayRef<MinidumpThread>
329   ParseThreadList(llvm::ArrayRef<uint8_t> &data);
330 };
331 static_assert(sizeof(MinidumpThread) == 48,
332               "sizeof MinidumpThread is not correct!");
333
334 // Reference:
335 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
336 union MinidumpCPUInfo {
337   struct {
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 */
343   } x86_cpu_info;
344   struct {
345     llvm::support::ulittle32_t cpuid;
346     llvm::support::ulittle32_t elf_hwcaps; /* linux specific, 0 otherwise */
347   } arm_cpu_info;
348   struct {
349     llvm::support::ulittle64_t processor_features[2];
350   } other_cpu_info;
351 };
352 static_assert(sizeof(MinidumpCPUInfo) == 24,
353               "sizeof MinidumpCPUInfo is not correct!");
354
355 // Reference:
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;
361
362   uint8_t number_of_processors;
363   uint8_t product_type;
364
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;
370
371   llvm::support::ulittle16_t suit_mask;
372   llvm::support::ulittle16_t reserved2;
373
374   MinidumpCPUInfo cpu;
375
376   static const MinidumpSystemInfo *Parse(llvm::ArrayRef<uint8_t> &data);
377 };
378 static_assert(sizeof(MinidumpSystemInfo) == 56,
379               "sizeof MinidumpSystemInfo is not correct!");
380
381 // TODO misc2, misc3 ?
382 // Reference:
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;
392
393   static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data);
394
395   llvm::Optional<lldb::pid_t> GetPid() const;
396 };
397 static_assert(sizeof(MinidumpMiscInfo) == 24,
398               "sizeof MinidumpMiscInfo is not correct!");
399
400 // The /proc/pid/status is saved as an ascii string in the file
401 class LinuxProcStatus {
402 public:
403   llvm::StringRef proc_status;
404   lldb::pid_t pid;
405
406   static llvm::Optional<LinuxProcStatus> Parse(llvm::ArrayRef<uint8_t> &data);
407
408   lldb::pid_t GetPid() const;
409
410 private:
411   LinuxProcStatus() = default;
412 };
413
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;
430 };
431 static_assert(sizeof(MinidumpVSFixedFileInfo) == 52,
432               "sizeof MinidumpVSFixedFileInfo is not correct!");
433
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];
445
446   static const MinidumpModule *Parse(llvm::ArrayRef<uint8_t> &data);
447
448   static llvm::ArrayRef<MinidumpModule>
449   ParseModuleList(llvm::ArrayRef<uint8_t> &data);
450 };
451 static_assert(sizeof(MinidumpModule) == 108,
452               "sizeof MinidumpVSFixedFileInfo is not correct!");
453
454 // Exception stuff
455 struct MinidumpException {
456   enum : unsigned {
457     ExceptonInfoMaxParams = 15,
458     DumpRequested = 0xFFFFFFFF,
459   };
460
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];
468 };
469 static_assert(sizeof(MinidumpException) == 152,
470               "sizeof MinidumpException is not correct!");
471
472 struct MinidumpExceptionStream {
473   llvm::support::ulittle32_t thread_id;
474   llvm::support::ulittle32_t alignment;
475   MinidumpException exception_record;
476   MinidumpLocationDescriptor thread_context;
477
478   static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
479 };
480 static_assert(sizeof(MinidumpExceptionStream) == 168,
481               "sizeof MinidumpExceptionStream is not correct!");
482
483 } // namespace minidump
484 } // namespace lldb_private
485 #endif // liblldb_MinidumpTypes_h_