1 #[repr(C)] 2 #[derive(Debug, Default, PartialEq)] 3 pub struct MDGUID { 4 data1: u32, 5 data2: u16, 6 data3: u16, 7 data4: [u8; 8], 8 } 9 10 #[repr(C)] 11 #[derive(Debug, Default, PartialEq, Clone, Copy)] 12 pub struct MDVSFixedFileInfo { 13 pub signature: u32, 14 pub struct_version: u32, 15 pub file_version_hi: u32, 16 pub file_version_lo: u32, 17 pub product_version_hi: u32, 18 pub product_version_lo: u32, 19 pub file_flags_mask: u32, /* Identifies valid bits in fileFlags */ 20 pub file_flags: u32, 21 pub file_os: u32, 22 pub file_type: u32, 23 pub file_subtype: u32, 24 pub file_date_hi: u32, 25 pub file_date_lo: u32, 26 } 27 28 /* An MDRVA is an offset into the minidump file. The beginning of the 29 * MDRawHeader is at offset 0. */ 30 pub type MDRVA = u32; 31 32 #[repr(C)] 33 #[derive(Debug, Default, Clone, Copy, PartialEq)] 34 pub struct MDLocationDescriptor { 35 pub data_size: u32, 36 pub rva: MDRVA, 37 } 38 39 #[repr(C)] 40 #[derive(Debug, Default, Clone, PartialEq)] 41 pub struct MDMemoryDescriptor { 42 /* The base address of the memory range on the host that produced the 43 * minidump. */ 44 pub start_of_memory_range: u64, 45 pub memory: MDLocationDescriptor, 46 } 47 48 #[repr(C)] 49 #[derive(Debug, Default, PartialEq)] 50 pub struct MDRawHeader { 51 pub signature: u32, 52 pub version: u32, 53 pub stream_count: u32, 54 pub stream_directory_rva: MDRVA, /* A |stream_count|-sized array of 55 * MDRawDirectory structures. */ 56 pub checksum: u32, /* Can be 0. In fact, that's all that's 57 * been found in minidump files. */ 58 pub time_date_stamp: u32, /* time_t */ 59 pub flags: u64, 60 } 61 62 /* For (MDRawHeader).signature and (MDRawHeader).version. Note that only the 63 * low 16 bits of (MDRawHeader).version are MD_HEADER_VERSION. Per the 64 * documentation, the high 16 bits are implementation-specific. */ 65 pub const MD_HEADER_SIGNATURE: u32 = 0x504d444d; /* 'PMDM' */ 66 /* MINIDUMP_SIGNATURE */ 67 pub const MD_HEADER_VERSION: u32 = 0x0000a793; /* 42899 */ 68 /* MINIDUMP_VERSION */ 69 70 /// The name of a thread, found in the ThreadNamesStream. 71 #[repr(C, packed)] 72 #[derive(Clone, Copy, Debug, Default, PartialEq)] 73 pub struct MDRawThreadName { 74 /// The id of the thread. 75 pub thread_id: u32, 76 /// Where the name of the thread is stored (yes, the legendary RVA64 is real!!). 77 pub thread_name_rva: u64, 78 } 79 80 #[repr(C)] 81 #[derive(Debug, Default, PartialEq)] 82 pub struct MDRawThread { 83 pub thread_id: u32, 84 pub suspend_count: u32, 85 pub priority_class: u32, 86 pub priority: u32, 87 pub teb: u64, /* Thread environment block */ 88 pub stack: MDMemoryDescriptor, 89 pub thread_context: MDLocationDescriptor, /* MDRawContext[CPU] */ 90 } 91 92 pub type MDRawThreadList = Vec<MDRawThread>; 93 94 /* The inclusion of a 64-bit type in MINIDUMP_MODULE forces the struct to 95 * be tail-padded out to a multiple of 64 bits under some ABIs (such as PPC). 96 * This doesn't occur on systems that don't tail-pad in this manner. Define 97 * this macro to be the usable size of the MDRawModule struct, and use it in 98 * place of sizeof(MDRawModule). */ 99 // pub const MD_MODULE_SIZE: usize = 108; 100 // NOTE: We use "packed" here instead, to size_of::<MDRawModule>() == 108 101 // "packed" should be safe here, as we don't address reserved{0,1} at all 102 // and padding should happen only at the tail 103 #[repr(C, packed)] 104 #[derive(Clone, Copy, Debug, Default, PartialEq)] 105 pub struct MDRawModule { 106 pub base_of_image: u64, 107 pub size_of_image: u32, 108 pub checksum: u32, /* 0 if unknown */ 109 pub time_date_stamp: u32, /* time_t */ 110 pub module_name_rva: MDRVA, /* MDString, pathname or filename */ 111 pub version_info: MDVSFixedFileInfo, 112 113 /* The next field stores a CodeView record and is populated when a module's 114 * debug information resides in a PDB file. It identifies the PDB file. */ 115 pub cv_record: MDLocationDescriptor, 116 117 /* The next field is populated when a module's debug information resides 118 * in a DBG file. It identifies the DBG file. This field is effectively 119 * obsolete with modules built by recent toolchains. */ 120 pub misc_record: MDLocationDescriptor, 121 122 /* Alignment problem: reserved0 and reserved1 are defined by the platform 123 * SDK as 64-bit quantities. However, that results in a structure whose 124 * alignment is unpredictable on different CPUs and ABIs. If the ABI 125 * specifies full alignment of 64-bit quantities in structures (as ppc 126 * does), there will be padding between miscRecord and reserved0. If 127 * 64-bit quantities can be aligned on 32-bit boundaries (as on x86), 128 * this padding will not exist. (Note that the structure up to this point 129 * contains 1 64-bit member followed by 21 32-bit members.) 130 * As a workaround, reserved0 and reserved1 are instead defined here as 131 * four 32-bit quantities. This should be harmless, as there are 132 * currently no known uses for these fields. */ 133 pub reserved0: [u32; 2], 134 pub reserved1: [u32; 2], 135 } 136 137 #[repr(C)] 138 #[derive(Debug, Default, PartialEq, Clone)] 139 pub struct MDRawDirectory { 140 pub stream_type: u32, 141 pub location: MDLocationDescriptor, 142 } 143 144 #[repr(C)] 145 #[derive(Debug, Default, PartialEq)] 146 pub struct MDException { 147 pub exception_code: u32, /* Windows: MDExceptionCodeWin, 148 * Mac OS X: MDExceptionMac, 149 * Linux: MDExceptionCodeLinux. */ 150 pub exception_flags: u32, /* Windows: 1 if noncontinuable, 151 Mac OS X: MDExceptionCodeMac. */ 152 pub exception_record: u64, /* Address (in the minidump-producing host's 153 * memory) of another MDException, for 154 * nested exceptions. */ 155 pub exception_address: u64, /* The address that caused the exception. 156 * Mac OS X: exception subcode (which is 157 * typically the address). */ 158 pub number_parameters: u32, /* Number of valid elements in 159 * exception_information. */ 160 pub __align: u32, 161 pub exception_information: [u64; 15], 162 } 163 164 #[repr(C)] 165 #[derive(Debug, Default, PartialEq)] 166 pub struct MDRawExceptionStream { 167 pub thread_id: u32, /* Thread in which the exception 168 * occurred. Corresponds to 169 * (MDRawThread).thread_id. */ 170 pub __align: u32, 171 pub exception_record: MDException, 172 pub thread_context: MDLocationDescriptor, /* MDRawContext[CPU] */ 173 } 174 175 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] 176 #[repr(C)] 177 #[derive(Debug, Default, PartialEq)] 178 pub struct MDCPUInformation { 179 pub vendor_id: [u32; 3], /* cpuid 0: ebx, edx, ecx */ 180 pub version_information: u32, /* cpuid 1: eax */ 181 pub feature_information: u32, /* cpuid 1: edx */ 182 pub amd_extended_cpu_features: u32, /* cpuid 0x80000001, ebx */ 183 } 184 185 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 186 #[repr(C)] 187 #[derive(Debug, Default, PartialEq)] 188 pub struct MDCPUInformation { 189 pub cpuid: u32, 190 pub elf_hwcaps: u32, /* linux specific, 0 otherwise */ 191 _padding: [u32; 4], 192 } 193 194 #[cfg(target_arch = "mips")] 195 #[repr(C)] 196 #[derive(Debug, Default, PartialEq)] 197 pub struct MDCPUInformation { 198 pub cpuid: [u64; 2], 199 _padding: [u32; 2], 200 } 201 202 /* For (MDCPUInformation).arm_cpu_info.elf_hwcaps. 203 * This matches the Linux kernel definitions from <asm/hwcaps.h> */ 204 #[repr(u32)] 205 pub enum MDCPUInformationARMElfHwCaps { 206 Swp = 1 << 0, 207 Half = 1 << 1, 208 Thumb = 1 << 2, 209 Bit26 = 1 << 3, 210 FastMult = 1 << 4, 211 Fpa = 1 << 5, 212 Vfp = 1 << 6, 213 Edsp = 1 << 7, 214 Java = 1 << 8, 215 Iwmmxt = 1 << 9, 216 Crunch = 1 << 10, 217 Thumbee = 1 << 11, 218 Neon = 1 << 12, 219 Vfpv3 = 1 << 13, 220 Vfpv3d16 = 1 << 14, 221 Tls = 1 << 15, 222 Vfpv4 = 1 << 16, 223 Idiva = 1 << 17, 224 Idivt = 1 << 18, 225 } 226 227 #[repr(C)] 228 #[derive(Debug, Default, PartialEq)] 229 pub struct MDRawSystemInfo { 230 /* The next 3 fields and numberOfProcessors are from the SYSTEM_INFO 231 * structure as returned by GetSystemInfo */ 232 pub processor_architecture: u16, 233 pub processor_level: u16, /* x86: 5 = 586, 6 = 686, ... */ 234 /* ARM: 6 = ARMv6, 7 = ARMv7 ... */ 235 pub processor_revision: u16, /* x86: 0xMMSS, where MM=model, 236 * SS=stepping */ 237 /* ARM: 0 */ 238 pub number_of_processors: u8, 239 pub product_type: u8, /* Windows: VER_NT_* from WinNT.h */ 240 241 /* The next 5 fields are from the OSVERSIONINFO structure as returned 242 * by GetVersionEx */ 243 pub major_version: u32, 244 pub minor_version: u32, 245 pub build_number: u32, 246 pub platform_id: u32, 247 pub csd_version_rva: MDRVA, /* MDString further identifying the 248 * host OS. 249 * Windows: name of the installed OS 250 * service pack. 251 * Mac OS X: the Apple OS build number 252 * (sw_vers -buildVersion). 253 * Linux: uname -srvmo */ 254 255 pub suite_mask: u16, /* Windows: VER_SUITE_* from WinNT.h */ 256 pub reserved2: u16, 257 258 pub cpu: MDCPUInformation, 259 } 260 261 #[cfg(target_pointer_width = "64")] 262 #[derive(Debug, Default, PartialEq)] 263 pub struct MDRawLinkMap { 264 pub addr: u64, 265 pub name: MDRVA, 266 pub ld: u64, 267 } 268 269 #[cfg(target_pointer_width = "64")] 270 #[derive(Debug, Default, PartialEq)] 271 pub struct MDRawDebug { 272 pub version: u32, 273 pub map: MDRVA, /* array of MDRawLinkMap64 */ 274 pub dso_count: u32, 275 pub brk: u64, 276 pub ldbase: u64, 277 pub dynamic: u64, 278 } 279 280 #[cfg(target_pointer_width = "32")] 281 #[derive(Debug, Default, PartialEq)] 282 pub struct MDRawLinkMap { 283 pub addr: u32, 284 pub name: MDRVA, 285 pub ld: u32, 286 } 287 288 #[cfg(target_pointer_width = "32")] 289 #[derive(Debug, Default, PartialEq)] 290 pub struct MDRawDebug { 291 pub version: u32, 292 pub map: MDRVA, /* array of MDRawLinkMap32 */ 293 pub dso_count: u32, 294 pub brk: u32, 295 pub ldbase: u32, 296 pub dynamic: u32, 297 } 298 299 /* For (MDRawSystemInfo).processor_architecture: */ 300 #[repr(u16)] 301 pub enum MDCPUArchitecture { 302 X86 = 0, /* PROCESSOR_ARCHITECTURE_INTEL */ 303 Mips = 1, /* PROCESSOR_ARCHITECTURE_MIPS */ 304 Alpha = 2, /* PROCESSOR_ARCHITECTURE_ALPHA */ 305 Ppc = 3, /* PROCESSOR_ARCHITECTURE_PPC */ 306 Shx = 4, /* PROCESSOR_ARCHITECTURE_SHX 307 * (Super-H) */ 308 Arm = 5, /* PROCESSOR_ARCHITECTURE_ARM */ 309 Ia64 = 6, /* PROCESSOR_ARCHITECTURE_IA64 */ 310 Alpha64 = 7, /* PROCESSOR_ARCHITECTURE_ALPHA64 */ 311 Msil = 8, /* PROCESSOR_ARCHITECTURE_MSIL 312 * (Microsoft Intermediate Language) */ 313 Amd64 = 9, /* PROCESSOR_ARCHITECTURE_AMD64 */ 314 X86Win64 = 10, 315 /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */ 316 Arm64 = 12, /* PROCESSOR_ARCHITECTURE_ARM64 */ 317 Sparc = 0x8001, /* Breakpad-defined value for SPARC */ 318 Ppc64 = 0x8002, /* Breakpad-defined value for PPC64 */ 319 Arm64Old = 0x8003, /* Breakpad-defined value for ARM64 */ 320 Mips64 = 0x8004, /* Breakpad-defined value for MIPS64 */ 321 Unknown = 0xffff, /* PROCESSOR_ARCHITECTURE_UNKNOWN */ 322 } 323 324 /* For (MDRawSystemInfo).platform_id: */ 325 #[repr(u32)] 326 pub enum MDOSPlatform { 327 Win32s = 0, /* VER_PLATFORM_WIN32s (Windows 3.1) */ 328 Win32Windows = 1, /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */ 329 Win32Nt = 2, /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */ 330 Win32Ce = 3, /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH 331 * (Windows CE, Windows Mobile, "Handheld") */ 332 /* The following values are Breakpad-defined. */ 333 Unix = 0x8000, /* Generic Unix-ish */ 334 MacOsX = 0x8101, /* Mac OS X/Darwin */ 335 Ios = 0x8102, /* iOS */ 336 Linux = 0x8201, /* Linux */ 337 Solaris = 0x8202, /* Solaris */ 338 Android = 0x8203, /* Android */ 339 Ps3 = 0x8204, /* PS3 */ 340 Nacl = 0x8205, /* Native Client (NaCl) */ 341 Fuchsia = 0x8206, /* Fuchsia */ 342 } 343 344 /* 345 * Modern ELF toolchains insert a "build id" into the ELF headers that 346 * usually contains a hash of some ELF headers + sections to uniquely 347 * identify a binary. 348 * 349 * https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Developer_Guide/compiling-build-id.html 350 * https://sourceware.org/binutils/docs-2.26/ld/Options.html#index-g_t_002d_002dbuild_002did-292 351 */ 352 pub const MD_CVINFOELF_SIGNATURE: u32 = 0x4270454c; /* cvSignature = 'BpEL' */ 353 /* Signature is followed by the bytes of the 354 * build id from GNU_BUILD_ID ELF note. 355 * This is variable-length, but usually 20 bytes 356 * as the binutils ld default is a SHA-1 hash. */ 357 358 /* For (MDRawHeader).flags: */ 359 pub enum MDType { 360 /* MD_NORMAL is the standard type of minidump. It includes full 361 * streams for the thread list, module list, exception, system info, 362 * and miscellaneous info. A memory list stream is also present, 363 * pointing to the same stack memory contained in the thread list, 364 * as well as a 256-byte region around the instruction address that 365 * was executing when the exception occurred. Stack memory is from 366 * 4 bytes below a thread's stack pointer up to the top of the 367 * memory region encompassing the stack. */ 368 Normal = 0x00000000, 369 WithDataSegs = 0x00000001, 370 WithFullMemory = 0x00000002, 371 WithHandleData = 0x00000004, 372 FilterMemory = 0x00000008, 373 ScanMemory = 0x00000010, 374 WithUnloadedModules = 0x00000020, 375 WithIndirectlyReferencedMemory = 0x00000040, 376 FilterModulePaths = 0x00000080, 377 WithProcessThreadData = 0x00000100, 378 WithPrivateReadWriteMemory = 0x00000200, 379 WithoutOptionalData = 0x00000400, 380 WithFullMemoryInfo = 0x00000800, 381 WithThreadInfo = 0x00001000, 382 WithCodeSegs = 0x00002000, 383 WithoutAuxilliarySegs = 0x00004000, 384 WithFullAuxilliaryState = 0x00008000, 385 WithPrivateWriteCopyMemory = 0x00010000, 386 IgnoreInaccessibleMemory = 0x00020000, 387 WithTokenInformation = 0x00040000, 388 } 389 390 /* For (MDRawDirectory).stream_type */ 391 #[repr(u32)] 392 pub enum MDStreamType { 393 UnusedStream = 0, 394 ReservedStream0 = 1, 395 ReservedStream1 = 2, 396 ThreadListStream = 3, /* MDRawThreadList */ 397 ModuleListStream = 4, /* MDRawModuleList */ 398 MemoryListStream = 5, /* MDRawMemoryList */ 399 ExceptionStream = 6, /* MDRawExceptionStream */ 400 SystemInfoStream = 7, /* MDRawSystemInfo */ 401 ThreadExListStream = 8, 402 Memory64ListStream = 9, 403 CommentStreamA = 10, 404 CommentStreamW = 11, 405 HandleDataStream = 12, 406 FunctionTableStream = 13, 407 UnloadedModuleListStream = 14, 408 MiscInfoStream = 15, /* MDRawMiscInfo */ 409 MemoryInfoListStream = 16, /* MDRawMemoryInfoList */ 410 ThreadInfoListStream = 17, 411 HandleOperationListStream = 18, 412 TokenStream = 19, 413 JavascriptDataStream = 20, 414 SystemMemoryInfoStream = 21, 415 ProcessVmCountersStream = 22, 416 IptTraceStream = 23, 417 ThreadNamesStream = 24, 418 LastReservedStream = 0x0000ffff, 419 420 /* Breakpad extension types. 0x4767 = "Gg" */ 421 BreakpadInfoStream = 0x47670001, /* MDRawBreakpadInfo */ 422 AssertionInfoStream = 0x47670002, /* MDRawAssertionInfo */ 423 /* These are additional minidump stream values which are specific to 424 * the linux breakpad implementation. */ 425 LinuxCpuInfo = 0x47670003, /* /proc/cpuinfo */ 426 LinuxProcStatus = 0x47670004, /* /proc/$x/status */ 427 LinuxLsbRelease = 0x47670005, /* /etc/lsb-release */ 428 LinuxCmdLine = 0x47670006, /* /proc/$x/cmdline */ 429 LinuxEnviron = 0x47670007, /* /proc/$x/environ */ 430 LinuxAuxv = 0x47670008, /* /proc/$x/auxv */ 431 LinuxMaps = 0x47670009, /* /proc/$x/maps */ 432 LinuxDsoDebug = 0x4767000A, /* MDRawDebug{32,64} */ 433 434 /* Crashpad extension types. 0x4350 = "CP" 435 * See Crashpad's minidump/minidump_extensions.h. */ 436 CrashpadInfoStream = 0x43500001, /* MDRawCrashpadInfo */ 437 } 438