]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
MFV r333779: xz 5.2.4.
[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 // Reference:
47 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx
48 enum class MinidumpStreamType : uint32_t {
49   Unused = 0,
50   Reserved0 = 1,
51   Reserved1 = 2,
52   ThreadList = 3,
53   ModuleList = 4,
54   MemoryList = 5,
55   Exception = 6,
56   SystemInfo = 7,
57   ThreadExList = 8,
58   Memory64List = 9,
59   CommentA = 10,
60   CommentW = 11,
61   HandleData = 12,
62   FunctionTable = 13,
63   UnloadedModuleList = 14,
64   MiscInfo = 15,
65   MemoryInfoList = 16,
66   ThreadInfoList = 17,
67   HandleOperationList = 18,
68   Token = 19,
69   JavascriptData = 20,
70   SystemMemoryInfo = 21,
71   ProcessVMCounters = 22,
72   LastReserved = 0x0000ffff,
73
74   /* Breakpad extension types.  0x4767 = "Gg" */
75   BreakpadInfo = 0x47670001,
76   AssertionInfo = 0x47670002,
77   /* These are additional minidump stream values which are specific to
78    * the linux breakpad implementation.   */
79   LinuxCPUInfo = 0x47670003,    /* /proc/cpuinfo      */
80   LinuxProcStatus = 0x47670004, /* /proc/$x/status    */
81   LinuxLSBRelease = 0x47670005, /* /etc/lsb-release   */
82   LinuxCMDLine = 0x47670006,    /* /proc/$x/cmdline   */
83   LinuxEnviron = 0x47670007,    /* /proc/$x/environ   */
84   LinuxAuxv = 0x47670008,       /* /proc/$x/auxv      */
85   LinuxMaps = 0x47670009,       /* /proc/$x/maps      */
86   LinuxDSODebug = 0x4767000A
87 };
88
89 // for MinidumpSystemInfo.processor_arch
90 enum class MinidumpCPUArchitecture : uint16_t {
91   X86 = 0,         /* PROCESSOR_ARCHITECTURE_INTEL */
92   MIPS = 1,        /* PROCESSOR_ARCHITECTURE_MIPS */
93   Alpha = 2,       /* PROCESSOR_ARCHITECTURE_ALPHA */
94   PPC = 3,         /* PROCESSOR_ARCHITECTURE_PPC */
95   SHX = 4,         /* PROCESSOR_ARCHITECTURE_SHX (Super-H) */
96   ARM = 5,         /* PROCESSOR_ARCHITECTURE_ARM */
97   IA64 = 6,        /* PROCESSOR_ARCHITECTURE_IA64 */
98   Alpha64 = 7,     /* PROCESSOR_ARCHITECTURE_ALPHA64 */
99   MSIL = 8,        /* PROCESSOR_ARCHITECTURE_MSIL
100                                               * (Microsoft Intermediate Language) */
101   AMD64 = 9,       /* PROCESSOR_ARCHITECTURE_AMD64 */
102   X86Win64 = 10,   /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
103   SPARC = 0x8001,  /* Breakpad-defined value for SPARC */
104   PPC64 = 0x8002,  /* Breakpad-defined value for PPC64 */
105   ARM64 = 0x8003,  /* Breakpad-defined value for ARM64 */
106   MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */
107   Unknown = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */
108 };
109
110 // for MinidumpSystemInfo.platform_id
111 enum class MinidumpOSPlatform : uint32_t {
112   Win32S = 0,       /* VER_PLATFORM_WIN32s (Windows 3.1) */
113   Win32Windows = 1, /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
114   Win32NT = 2,      /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
115   Win32CE = 3,      /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
116                                   * (Windows CE, Windows Mobile, "Handheld") */
117
118   /* The following values are Breakpad-defined. */
119   Unix = 0x8000,    /* Generic Unix-ish */
120   MacOSX = 0x8101,  /* Mac OS X/Darwin */
121   IOS = 0x8102,     /* iOS */
122   Linux = 0x8201,   /* Linux */
123   Solaris = 0x8202, /* Solaris */
124   Android = 0x8203, /* Android */
125   PS3 = 0x8204,     /* PS3 */
126   NaCl = 0x8205     /* Native Client (NaCl) */
127 };
128
129 // For MinidumpCPUInfo.arm_cpu_info.elf_hwcaps.
130 // This matches the Linux kernel definitions from <asm/hwcaps.h>
131 enum class MinidumpPCPUInformationARMElfHwCaps : uint32_t {
132   SWP = (1 << 0),
133   Half = (1 << 1),
134   Thumb = (1 << 2),
135   _26BIT = (1 << 3),
136   FastMult = (1 << 4),
137   FPA = (1 << 5),
138   VFP = (1 << 6),
139   EDSP = (1 << 7),
140   Java = (1 << 8),
141   IWMMXT = (1 << 9),
142   Crunch = (1 << 10),
143   ThumbEE = (1 << 11),
144   Neon = (1 << 12),
145   VFPv3 = (1 << 13),
146   VFPv3D16 = (1 << 14),
147   TLS = (1 << 15),
148   VFPv4 = (1 << 16),
149   IDIVA = (1 << 17),
150   IDIVT = (1 << 18),
151   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IDIVT)
152 };
153
154 enum class MinidumpMiscInfoFlags : uint32_t {
155   ProcessID = (1 << 0),
156   ProcessTimes = (1 << 1),
157   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)
158 };
159
160 template <typename T>
161 Status consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) {
162   Status error;
163   if (Buffer.size() < sizeof(T)) {
164     error.SetErrorString("Insufficient buffer!");
165     return error;
166   }
167
168   Object = reinterpret_cast<const T *>(Buffer.data());
169   Buffer = Buffer.drop_front(sizeof(T));
170   return error;
171 }
172
173 // parse a MinidumpString which is with UTF-16
174 // Reference:
175 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680395(v=vs.85).aspx
176 llvm::Optional<std::string> parseMinidumpString(llvm::ArrayRef<uint8_t> &data);
177
178 // Reference:
179 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680378(v=vs.85).aspx
180 struct MinidumpHeader {
181   llvm::support::ulittle32_t signature;
182   llvm::support::ulittle32_t
183       version; // The high 16 bits of version field are implementation specific
184   llvm::support::ulittle32_t streams_count;
185   llvm::support::ulittle32_t
186       stream_directory_rva; // offset of the stream directory
187   llvm::support::ulittle32_t checksum;
188   llvm::support::ulittle32_t time_date_stamp; // time_t format
189   llvm::support::ulittle64_t flags;
190
191   static const MinidumpHeader *Parse(llvm::ArrayRef<uint8_t> &data);
192 };
193 static_assert(sizeof(MinidumpHeader) == 32,
194               "sizeof MinidumpHeader is not correct!");
195
196 // Reference:
197 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680383.aspx
198 struct MinidumpLocationDescriptor {
199   llvm::support::ulittle32_t data_size;
200   llvm::support::ulittle32_t rva;
201 };
202 static_assert(sizeof(MinidumpLocationDescriptor) == 8,
203               "sizeof MinidumpLocationDescriptor is not correct!");
204
205 // Reference:
206 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680384(v=vs.85).aspx
207 struct MinidumpMemoryDescriptor {
208   llvm::support::ulittle64_t start_of_memory_range;
209   MinidumpLocationDescriptor memory;
210
211   static llvm::ArrayRef<MinidumpMemoryDescriptor>
212   ParseMemoryList(llvm::ArrayRef<uint8_t> &data);
213 };
214 static_assert(sizeof(MinidumpMemoryDescriptor) == 16,
215               "sizeof MinidumpMemoryDescriptor is not correct!");
216
217 struct MinidumpMemoryDescriptor64 {
218   llvm::support::ulittle64_t start_of_memory_range;
219   llvm::support::ulittle64_t data_size;
220
221   static std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
222   ParseMemory64List(llvm::ArrayRef<uint8_t> &data);
223 };
224 static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
225               "sizeof MinidumpMemoryDescriptor64 is not correct!");
226
227 // Reference:
228 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680365.aspx
229 struct MinidumpDirectory {
230   llvm::support::ulittle32_t stream_type;
231   MinidumpLocationDescriptor location;
232 };
233 static_assert(sizeof(MinidumpDirectory) == 12,
234               "sizeof MinidumpDirectory is not correct!");
235
236 // Reference:
237 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx
238 struct MinidumpMemoryInfoListHeader {
239   llvm::support::ulittle32_t size_of_header;
240   llvm::support::ulittle32_t size_of_entry;
241   llvm::support::ulittle64_t num_of_entries;
242 };
243 static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
244               "sizeof MinidumpMemoryInfoListHeader is not correct!");
245
246 // Reference:
247 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
248 struct MinidumpMemoryInfo {
249   llvm::support::ulittle64_t base_address;
250   llvm::support::ulittle64_t allocation_base;
251   llvm::support::ulittle32_t allocation_protect;
252   llvm::support::ulittle32_t alignment1;
253   llvm::support::ulittle64_t region_size;
254   llvm::support::ulittle32_t state;
255   llvm::support::ulittle32_t protect;
256   llvm::support::ulittle32_t type;
257   llvm::support::ulittle32_t alignment2;
258
259   static std::vector<const MinidumpMemoryInfo *>
260   ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
261 };
262 static_assert(sizeof(MinidumpMemoryInfo) == 48,
263               "sizeof MinidumpMemoryInfo is not correct!");
264
265 enum class MinidumpMemoryInfoState : uint32_t {
266   MemCommit = 0x1000,
267   MemFree = 0x10000,
268   MemReserve = 0x2000,
269   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
270 };
271
272 enum class MinidumpMemoryInfoType : uint32_t {
273   MemImage = 0x1000000,
274   MemMapped = 0x40000,
275   MemPrivate = 0x20000,
276   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
277 };
278
279 // Reference:
280 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
281 enum class MinidumpMemoryProtectionContants : uint32_t {
282   PageExecute = 0x10,
283   PageExecuteRead = 0x20,
284   PageExecuteReadWrite = 0x40,
285   PageExecuteWriteCopy = 0x80,
286   PageNoAccess = 0x01,
287   PageReadOnly = 0x02,
288   PageReadWrite = 0x04,
289   PageWriteCopy = 0x08,
290   PageTargetsInvalid = 0x40000000,
291   PageTargetsNoUpdate = 0x40000000,
292
293   PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
294                  PageWriteCopy,
295   PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
296                    PageExecuteWriteCopy,
297   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
298 };
299
300 // Reference:
301 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx
302 struct MinidumpThread {
303   llvm::support::ulittle32_t thread_id;
304   llvm::support::ulittle32_t suspend_count;
305   llvm::support::ulittle32_t priority_class;
306   llvm::support::ulittle32_t priority;
307   llvm::support::ulittle64_t teb;
308   MinidumpMemoryDescriptor stack;
309   MinidumpLocationDescriptor thread_context;
310
311   static const MinidumpThread *Parse(llvm::ArrayRef<uint8_t> &data);
312
313   static llvm::ArrayRef<MinidumpThread>
314   ParseThreadList(llvm::ArrayRef<uint8_t> &data);
315 };
316 static_assert(sizeof(MinidumpThread) == 48,
317               "sizeof MinidumpThread is not correct!");
318
319 // Reference:
320 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
321 union MinidumpCPUInfo {
322   struct {
323     llvm::support::ulittle32_t vendor_id[3];        /* cpuid 0: ebx, edx, ecx */
324     llvm::support::ulittle32_t version_information; /* cpuid 1: eax */
325     llvm::support::ulittle32_t feature_information; /* cpuid 1: edx */
326     llvm::support::ulittle32_t
327         amd_extended_cpu_features; /* cpuid 0x80000001, ebx */
328   } x86_cpu_info;
329   struct {
330     llvm::support::ulittle32_t cpuid;
331     llvm::support::ulittle32_t elf_hwcaps; /* linux specific, 0 otherwise */
332   } arm_cpu_info;
333   struct {
334     llvm::support::ulittle64_t processor_features[2];
335   } other_cpu_info;
336 };
337 static_assert(sizeof(MinidumpCPUInfo) == 24,
338               "sizeof MinidumpCPUInfo is not correct!");
339
340 // Reference:
341 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
342 struct MinidumpSystemInfo {
343   llvm::support::ulittle16_t processor_arch;
344   llvm::support::ulittle16_t processor_level;
345   llvm::support::ulittle16_t processor_revision;
346
347   uint8_t number_of_processors;
348   uint8_t product_type;
349
350   llvm::support::ulittle32_t major_version;
351   llvm::support::ulittle32_t minor_version;
352   llvm::support::ulittle32_t build_number;
353   llvm::support::ulittle32_t platform_id;
354   llvm::support::ulittle32_t csd_version_rva;
355
356   llvm::support::ulittle16_t suit_mask;
357   llvm::support::ulittle16_t reserved2;
358
359   MinidumpCPUInfo cpu;
360
361   static const MinidumpSystemInfo *Parse(llvm::ArrayRef<uint8_t> &data);
362 };
363 static_assert(sizeof(MinidumpSystemInfo) == 56,
364               "sizeof MinidumpSystemInfo is not correct!");
365
366 // TODO misc2, misc3 ?
367 // Reference:
368 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
369 struct MinidumpMiscInfo {
370   llvm::support::ulittle32_t size;
371   // flags1 represents what info in the struct is valid
372   llvm::support::ulittle32_t flags1;
373   llvm::support::ulittle32_t process_id;
374   llvm::support::ulittle32_t process_create_time;
375   llvm::support::ulittle32_t process_user_time;
376   llvm::support::ulittle32_t process_kernel_time;
377
378   static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data);
379
380   llvm::Optional<lldb::pid_t> GetPid() const;
381 };
382 static_assert(sizeof(MinidumpMiscInfo) == 24,
383               "sizeof MinidumpMiscInfo is not correct!");
384
385 // The /proc/pid/status is saved as an ascii string in the file
386 class LinuxProcStatus {
387 public:
388   llvm::StringRef proc_status;
389   lldb::pid_t pid;
390
391   static llvm::Optional<LinuxProcStatus> Parse(llvm::ArrayRef<uint8_t> &data);
392
393   lldb::pid_t GetPid() const;
394
395 private:
396   LinuxProcStatus() = default;
397 };
398
399 // MinidumpModule stuff
400 struct MinidumpVSFixedFileInfo {
401   llvm::support::ulittle32_t signature;
402   llvm::support::ulittle32_t struct_version;
403   llvm::support::ulittle32_t file_version_hi;
404   llvm::support::ulittle32_t file_version_lo;
405   llvm::support::ulittle32_t product_version_hi;
406   llvm::support::ulittle32_t product_version_lo;
407   // file_flags_mask - identifies valid bits in fileFlags
408   llvm::support::ulittle32_t file_flags_mask;
409   llvm::support::ulittle32_t file_flags;
410   llvm::support::ulittle32_t file_os;
411   llvm::support::ulittle32_t file_type;
412   llvm::support::ulittle32_t file_subtype;
413   llvm::support::ulittle32_t file_date_hi;
414   llvm::support::ulittle32_t file_date_lo;
415 };
416 static_assert(sizeof(MinidumpVSFixedFileInfo) == 52,
417               "sizeof MinidumpVSFixedFileInfo is not correct!");
418
419 struct MinidumpModule {
420   llvm::support::ulittle64_t base_of_image;
421   llvm::support::ulittle32_t size_of_image;
422   llvm::support::ulittle32_t checksum;
423   llvm::support::ulittle32_t time_date_stamp;
424   llvm::support::ulittle32_t module_name_rva;
425   MinidumpVSFixedFileInfo version_info;
426   MinidumpLocationDescriptor CV_record;
427   MinidumpLocationDescriptor misc_record;
428   llvm::support::ulittle32_t reserved0[2];
429   llvm::support::ulittle32_t reserved1[2];
430
431   static const MinidumpModule *Parse(llvm::ArrayRef<uint8_t> &data);
432
433   static llvm::ArrayRef<MinidumpModule>
434   ParseModuleList(llvm::ArrayRef<uint8_t> &data);
435 };
436 static_assert(sizeof(MinidumpModule) == 108,
437               "sizeof MinidumpVSFixedFileInfo is not correct!");
438
439 // Exception stuff
440 struct MinidumpException {
441   enum : unsigned {
442     ExceptonInfoMaxParams = 15,
443     DumpRequested = 0xFFFFFFFF,
444   };
445
446   llvm::support::ulittle32_t exception_code;
447   llvm::support::ulittle32_t exception_flags;
448   llvm::support::ulittle64_t exception_record;
449   llvm::support::ulittle64_t exception_address;
450   llvm::support::ulittle32_t number_parameters;
451   llvm::support::ulittle32_t unused_alignment;
452   llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams];
453 };
454 static_assert(sizeof(MinidumpException) == 152,
455               "sizeof MinidumpException is not correct!");
456
457 struct MinidumpExceptionStream {
458   llvm::support::ulittle32_t thread_id;
459   llvm::support::ulittle32_t alignment;
460   MinidumpException exception_record;
461   MinidumpLocationDescriptor thread_context;
462
463   static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
464 };
465 static_assert(sizeof(MinidumpExceptionStream) == 168,
466               "sizeof MinidumpExceptionStream is not correct!");
467
468 } // namespace minidump
469 } // namespace lldb_private
470 #endif // liblldb_MinidumpTypes_h_