File: | tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp |
Warning: | line 68, column 33 Called C++ object pointer is uninitialized |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- RegisterContextMinidump_x86_64.cpp ----------------------*- 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 | // Project includes | |||
11 | #include "RegisterContextMinidump_x86_64.h" | |||
12 | ||||
13 | // Other libraries and framework includes | |||
14 | #include "lldb/Utility/DataBufferHeap.h" | |||
15 | ||||
16 | // C includes | |||
17 | // C++ includes | |||
18 | ||||
19 | using namespace lldb_private; | |||
20 | using namespace minidump; | |||
21 | ||||
22 | static llvm::MutableArrayRef<uint8_t> getDestRegister(uint8_t *context, | |||
23 | const RegisterInfo ®) { | |||
24 | auto bytes = reg.mutable_data(context); | |||
25 | ||||
26 | switch (reg.kinds[lldb::eRegisterKindLLDB]) { | |||
27 | case lldb_cs_x86_64: | |||
28 | case lldb_ds_x86_64: | |||
29 | case lldb_es_x86_64: | |||
30 | case lldb_fs_x86_64: | |||
31 | case lldb_gs_x86_64: | |||
32 | case lldb_ss_x86_64: | |||
33 | return bytes.take_front(2); | |||
34 | break; | |||
35 | case lldb_rflags_x86_64: | |||
36 | return bytes.take_front(4); | |||
37 | break; | |||
38 | default: | |||
39 | return bytes.take_front(8); | |||
40 | break; | |||
41 | } | |||
42 | } | |||
43 | ||||
44 | static void writeRegister(const void *reg_src, uint8_t *context, | |||
45 | const RegisterInfo ®) { | |||
46 | llvm::MutableArrayRef<uint8_t> reg_dest = getDestRegister(context, reg); | |||
47 | memcpy(reg_dest.data(), reg_src, reg_dest.size()); | |||
48 | } | |||
49 | ||||
50 | lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64( | |||
51 | llvm::ArrayRef<uint8_t> source_data, | |||
52 | RegisterInfoInterface *target_reg_interface) { | |||
53 | ||||
54 | const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo(); | |||
55 | ||||
56 | lldb::DataBufferSP result_context_buf( | |||
57 | new DataBufferHeap(target_reg_interface->GetGPRSize(), 0)); | |||
58 | uint8_t *result_base = result_context_buf->GetBytes(); | |||
59 | ||||
60 | if (source_data.size() < sizeof(MinidumpContext_x86_64)) | |||
| ||||
61 | return nullptr; | |||
62 | ||||
63 | const MinidumpContext_x86_64 *context; | |||
64 | consumeObject(source_data, context); | |||
65 | ||||
66 | const MinidumpContext_x86_64_Flags context_flags = | |||
67 | static_cast<MinidumpContext_x86_64_Flags>( | |||
68 | static_cast<uint32_t>(context->context_flags)); | |||
| ||||
69 | auto x86_64_Flag = MinidumpContext_x86_64_Flags::x86_64_Flag; | |||
70 | auto ControlFlag = MinidumpContext_x86_64_Flags::Control; | |||
71 | auto IntegerFlag = MinidumpContext_x86_64_Flags::Integer; | |||
72 | auto SegmentsFlag = MinidumpContext_x86_64_Flags::Segments; | |||
73 | ||||
74 | if ((context_flags & x86_64_Flag) != x86_64_Flag) | |||
75 | return nullptr; | |||
76 | ||||
77 | if ((context_flags & ControlFlag) == ControlFlag) { | |||
78 | writeRegister(&context->cs, result_base, reg_info[lldb_cs_x86_64]); | |||
79 | writeRegister(&context->ss, result_base, reg_info[lldb_ss_x86_64]); | |||
80 | writeRegister(&context->eflags, result_base, reg_info[lldb_rflags_x86_64]); | |||
81 | writeRegister(&context->rsp, result_base, reg_info[lldb_rsp_x86_64]); | |||
82 | writeRegister(&context->rip, result_base, reg_info[lldb_rip_x86_64]); | |||
83 | } | |||
84 | ||||
85 | if ((context_flags & SegmentsFlag) == SegmentsFlag) { | |||
86 | writeRegister(&context->ds, result_base, reg_info[lldb_ds_x86_64]); | |||
87 | writeRegister(&context->es, result_base, reg_info[lldb_es_x86_64]); | |||
88 | writeRegister(&context->fs, result_base, reg_info[lldb_fs_x86_64]); | |||
89 | writeRegister(&context->gs, result_base, reg_info[lldb_gs_x86_64]); | |||
90 | } | |||
91 | ||||
92 | if ((context_flags & IntegerFlag) == IntegerFlag) { | |||
93 | writeRegister(&context->rax, result_base, reg_info[lldb_rax_x86_64]); | |||
94 | writeRegister(&context->rcx, result_base, reg_info[lldb_rcx_x86_64]); | |||
95 | writeRegister(&context->rdx, result_base, reg_info[lldb_rdx_x86_64]); | |||
96 | writeRegister(&context->rbx, result_base, reg_info[lldb_rbx_x86_64]); | |||
97 | writeRegister(&context->rbp, result_base, reg_info[lldb_rbp_x86_64]); | |||
98 | writeRegister(&context->rsi, result_base, reg_info[lldb_rsi_x86_64]); | |||
99 | writeRegister(&context->rdi, result_base, reg_info[lldb_rdi_x86_64]); | |||
100 | writeRegister(&context->r8, result_base, reg_info[lldb_r8_x86_64]); | |||
101 | writeRegister(&context->r9, result_base, reg_info[lldb_r9_x86_64]); | |||
102 | writeRegister(&context->r10, result_base, reg_info[lldb_r10_x86_64]); | |||
103 | writeRegister(&context->r11, result_base, reg_info[lldb_r11_x86_64]); | |||
104 | writeRegister(&context->r12, result_base, reg_info[lldb_r12_x86_64]); | |||
105 | writeRegister(&context->r13, result_base, reg_info[lldb_r13_x86_64]); | |||
106 | writeRegister(&context->r14, result_base, reg_info[lldb_r14_x86_64]); | |||
107 | writeRegister(&context->r15, result_base, reg_info[lldb_r15_x86_64]); | |||
108 | } | |||
109 | ||||
110 | // TODO parse the floating point registers | |||
111 | ||||
112 | return result_context_buf; | |||
113 | } |
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()using ::llvm::BitmaskEnumDetail::operator~; using ::llvm::BitmaskEnumDetail ::operator|; using ::llvm::BitmaskEnumDetail::operator&; using ::llvm::BitmaskEnumDetail::operator^; using ::llvm::BitmaskEnumDetail ::operator|=; using ::llvm::BitmaskEnumDetail::operator&= ; using ::llvm::BitmaskEnumDetail::operator^=; |
38 | |
39 | enum class MinidumpHeaderConstants : uint32_t { |
40 | Signature = 0x504d444d, // 'PMDM' |
41 | Version = 0x0000a793, // 42899 |
42 | LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Signature)LLVM_BITMASK_LARGEST_ENUMERATOR = 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)LLVM_BITMASK_LARGEST_ENUMERATOR = 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)LLVM_BITMASK_LARGEST_ENUMERATOR = 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)LLVM_BITMASK_LARGEST_ENUMERATOR = 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)LLVM_BITMASK_LARGEST_ENUMERATOR = 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)LLVM_BITMASK_LARGEST_ENUMERATOR = 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_ |