1351278Sdim//===- Minidump.h - Minidump constants and structures -----------*- C++ -*-===// 2351278Sdim// 3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351278Sdim// See https://llvm.org/LICENSE.txt for license information. 5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351278Sdim// 7351278Sdim//===----------------------------------------------------------------------===// 8351278Sdim// 9351278Sdim// This header constants and data structures pertaining to the Windows Minidump 10351278Sdim// core file format. 11351278Sdim// 12351278Sdim// Reference: 13351278Sdim// https://msdn.microsoft.com/en-us/library/windows/desktop/ms679293(v=vs.85).aspx 14351278Sdim// https://chromium.googlesource.com/breakpad/breakpad/ 15351278Sdim// 16351278Sdim//===----------------------------------------------------------------------===// 17351278Sdim 18351278Sdim#ifndef LLVM_BINARYFORMAT_MINIDUMP_H 19351278Sdim#define LLVM_BINARYFORMAT_MINIDUMP_H 20351278Sdim 21360784Sdim#include "llvm/ADT/BitmaskEnum.h" 22351278Sdim#include "llvm/ADT/DenseMapInfo.h" 23351278Sdim#include "llvm/Support/Endian.h" 24351278Sdim 25351278Sdimnamespace llvm { 26351278Sdimnamespace minidump { 27351278Sdim 28360784SdimLLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); 29360784Sdim 30351278Sdim/// The minidump header is the first part of a minidump file. It identifies the 31351278Sdim/// file as a minidump file, and gives the location of the stream directory. 32351278Sdimstruct Header { 33351278Sdim static constexpr uint32_t MagicSignature = 0x504d444d; // PMDM 34351278Sdim static constexpr uint16_t MagicVersion = 0xa793; 35351278Sdim 36351278Sdim support::ulittle32_t Signature; 37351278Sdim // The high 16 bits of version field are implementation specific. The low 16 38351278Sdim // bits should be MagicVersion. 39351278Sdim support::ulittle32_t Version; 40351278Sdim support::ulittle32_t NumberOfStreams; 41351278Sdim support::ulittle32_t StreamDirectoryRVA; 42351278Sdim support::ulittle32_t Checksum; 43351278Sdim support::ulittle32_t TimeDateStamp; 44351278Sdim support::ulittle64_t Flags; 45351278Sdim}; 46351278Sdimstatic_assert(sizeof(Header) == 32, ""); 47351278Sdim 48351278Sdim/// The type of a minidump stream identifies its contents. Streams numbers after 49351278Sdim/// LastReserved are for application-defined data streams. 50351278Sdimenum class StreamType : uint32_t { 51351278Sdim#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) NAME = CODE, 52351278Sdim#include "llvm/BinaryFormat/MinidumpConstants.def" 53351278Sdim Unused = 0, 54351278Sdim LastReserved = 0x0000ffff, 55351278Sdim}; 56351278Sdim 57351278Sdim/// Specifies the location (and size) of various objects in the minidump file. 58351278Sdim/// The location is relative to the start of the file. 59351278Sdimstruct LocationDescriptor { 60351278Sdim support::ulittle32_t DataSize; 61351278Sdim support::ulittle32_t RVA; 62351278Sdim}; 63351278Sdimstatic_assert(sizeof(LocationDescriptor) == 8, ""); 64351278Sdim 65351278Sdim/// Describes a single memory range (both its VM address and where to find it in 66351278Sdim/// the file) of the process from which this minidump file was generated. 67351278Sdimstruct MemoryDescriptor { 68351278Sdim support::ulittle64_t StartOfMemoryRange; 69351278Sdim LocationDescriptor Memory; 70351278Sdim}; 71351278Sdimstatic_assert(sizeof(MemoryDescriptor) == 16, ""); 72351278Sdim 73360784Sdimstruct MemoryInfoListHeader { 74360784Sdim support::ulittle32_t SizeOfHeader; 75360784Sdim support::ulittle32_t SizeOfEntry; 76360784Sdim support::ulittle64_t NumberOfEntries; 77360784Sdim 78360784Sdim MemoryInfoListHeader() = default; 79360784Sdim MemoryInfoListHeader(uint32_t SizeOfHeader, uint32_t SizeOfEntry, 80360784Sdim uint64_t NumberOfEntries) 81360784Sdim : SizeOfHeader(SizeOfHeader), SizeOfEntry(SizeOfEntry), 82360784Sdim NumberOfEntries(NumberOfEntries) {} 83360784Sdim}; 84360784Sdimstatic_assert(sizeof(MemoryInfoListHeader) == 16, ""); 85360784Sdim 86360784Sdimenum class MemoryProtection : uint32_t { 87360784Sdim#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME) NAME = CODE, 88360784Sdim#include "llvm/BinaryFormat/MinidumpConstants.def" 89360784Sdim LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/0xffffffffu), 90360784Sdim}; 91360784Sdim 92360784Sdimenum class MemoryState : uint32_t { 93360784Sdim#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME) NAME = CODE, 94360784Sdim#include "llvm/BinaryFormat/MinidumpConstants.def" 95360784Sdim LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/0xffffffffu), 96360784Sdim}; 97360784Sdim 98360784Sdimenum class MemoryType : uint32_t { 99360784Sdim#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME) NAME = CODE, 100360784Sdim#include "llvm/BinaryFormat/MinidumpConstants.def" 101360784Sdim LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/0xffffffffu), 102360784Sdim}; 103360784Sdim 104360784Sdimstruct MemoryInfo { 105360784Sdim support::ulittle64_t BaseAddress; 106360784Sdim support::ulittle64_t AllocationBase; 107360784Sdim support::little_t<MemoryProtection> AllocationProtect; 108360784Sdim support::ulittle32_t Reserved0; 109360784Sdim support::ulittle64_t RegionSize; 110360784Sdim support::little_t<MemoryState> State; 111360784Sdim support::little_t<MemoryProtection> Protect; 112360784Sdim support::little_t<MemoryType> Type; 113360784Sdim support::ulittle32_t Reserved1; 114360784Sdim}; 115360784Sdimstatic_assert(sizeof(MemoryInfo) == 48, ""); 116360784Sdim 117351278Sdim/// Specifies the location and type of a single stream in the minidump file. The 118351278Sdim/// minidump stream directory is an array of entries of this type, with its size 119351278Sdim/// given by Header.NumberOfStreams. 120351278Sdimstruct Directory { 121351278Sdim support::little_t<StreamType> Type; 122351278Sdim LocationDescriptor Location; 123351278Sdim}; 124351278Sdimstatic_assert(sizeof(Directory) == 12, ""); 125351278Sdim 126351278Sdim/// The processor architecture of the system that generated this minidump. Used 127351278Sdim/// in the ProcessorArch field of the SystemInfo stream. 128351278Sdimenum class ProcessorArchitecture : uint16_t { 129351278Sdim#define HANDLE_MDMP_ARCH(CODE, NAME) NAME = CODE, 130351278Sdim#include "llvm/BinaryFormat/MinidumpConstants.def" 131351278Sdim}; 132351278Sdim 133351278Sdim/// The OS Platform of the system that generated this minidump. Used in the 134351278Sdim/// PlatformId field of the SystemInfo stream. 135351278Sdimenum class OSPlatform : uint32_t { 136351278Sdim#define HANDLE_MDMP_PLATFORM(CODE, NAME) NAME = CODE, 137351278Sdim#include "llvm/BinaryFormat/MinidumpConstants.def" 138351278Sdim}; 139351278Sdim 140351278Sdim/// Detailed information about the processor of the system that generated this 141351278Sdim/// minidump. Its interpretation depends on the ProcessorArchitecture enum. 142351278Sdimunion CPUInfo { 143351278Sdim struct X86Info { 144351278Sdim char VendorID[12]; // cpuid 0: ebx, edx, ecx 145351278Sdim support::ulittle32_t VersionInfo; // cpuid 1: eax 146351278Sdim support::ulittle32_t FeatureInfo; // cpuid 1: edx 147351278Sdim support::ulittle32_t AMDExtendedFeatures; // cpuid 0x80000001, ebx 148351278Sdim } X86; 149351278Sdim struct ArmInfo { 150351278Sdim support::ulittle32_t CPUID; 151351278Sdim support::ulittle32_t ElfHWCaps; // linux specific, 0 otherwise 152351278Sdim } Arm; 153351278Sdim struct OtherInfo { 154351278Sdim uint8_t ProcessorFeatures[16]; 155351278Sdim } Other; 156351278Sdim}; 157351278Sdimstatic_assert(sizeof(CPUInfo) == 24, ""); 158351278Sdim 159351278Sdim/// The SystemInfo stream, containing various information about the system where 160351278Sdim/// this minidump was generated. 161351278Sdimstruct SystemInfo { 162351278Sdim support::little_t<ProcessorArchitecture> ProcessorArch; 163351278Sdim support::ulittle16_t ProcessorLevel; 164351278Sdim support::ulittle16_t ProcessorRevision; 165351278Sdim 166351278Sdim uint8_t NumberOfProcessors; 167351278Sdim uint8_t ProductType; 168351278Sdim 169351278Sdim support::ulittle32_t MajorVersion; 170351278Sdim support::ulittle32_t MinorVersion; 171351278Sdim support::ulittle32_t BuildNumber; 172351278Sdim support::little_t<OSPlatform> PlatformId; 173351278Sdim support::ulittle32_t CSDVersionRVA; 174351278Sdim 175351278Sdim support::ulittle16_t SuiteMask; 176351278Sdim support::ulittle16_t Reserved; 177351278Sdim 178351278Sdim CPUInfo CPU; 179351278Sdim}; 180351278Sdimstatic_assert(sizeof(SystemInfo) == 56, ""); 181351278Sdim 182351278Sdimstruct VSFixedFileInfo { 183351278Sdim support::ulittle32_t Signature; 184351278Sdim support::ulittle32_t StructVersion; 185351278Sdim support::ulittle32_t FileVersionHigh; 186351278Sdim support::ulittle32_t FileVersionLow; 187351278Sdim support::ulittle32_t ProductVersionHigh; 188351278Sdim support::ulittle32_t ProductVersionLow; 189351278Sdim support::ulittle32_t FileFlagsMask; 190351278Sdim support::ulittle32_t FileFlags; 191351278Sdim support::ulittle32_t FileOS; 192351278Sdim support::ulittle32_t FileType; 193351278Sdim support::ulittle32_t FileSubtype; 194351278Sdim support::ulittle32_t FileDateHigh; 195351278Sdim support::ulittle32_t FileDateLow; 196351278Sdim}; 197351278Sdimstatic_assert(sizeof(VSFixedFileInfo) == 52, ""); 198351278Sdim 199351278Sdiminline bool operator==(const VSFixedFileInfo &LHS, const VSFixedFileInfo &RHS) { 200351278Sdim return memcmp(&LHS, &RHS, sizeof(VSFixedFileInfo)) == 0; 201351278Sdim} 202351278Sdim 203351278Sdimstruct Module { 204351278Sdim support::ulittle64_t BaseOfImage; 205351278Sdim support::ulittle32_t SizeOfImage; 206351278Sdim support::ulittle32_t Checksum; 207351278Sdim support::ulittle32_t TimeDateStamp; 208351278Sdim support::ulittle32_t ModuleNameRVA; 209351278Sdim VSFixedFileInfo VersionInfo; 210351278Sdim LocationDescriptor CvRecord; 211351278Sdim LocationDescriptor MiscRecord; 212351278Sdim support::ulittle64_t Reserved0; 213351278Sdim support::ulittle64_t Reserved1; 214351278Sdim}; 215351278Sdimstatic_assert(sizeof(Module) == 108, ""); 216351278Sdim 217351278Sdim/// Describes a single thread in the minidump file. Part of the ThreadList 218351278Sdim/// stream. 219351278Sdimstruct Thread { 220351278Sdim support::ulittle32_t ThreadId; 221351278Sdim support::ulittle32_t SuspendCount; 222351278Sdim support::ulittle32_t PriorityClass; 223351278Sdim support::ulittle32_t Priority; 224351278Sdim support::ulittle64_t EnvironmentBlock; 225351278Sdim MemoryDescriptor Stack; 226351278Sdim LocationDescriptor Context; 227351278Sdim}; 228351278Sdimstatic_assert(sizeof(Thread) == 48, ""); 229351278Sdim 230360784Sdimstruct Exception { 231360784Sdim static constexpr size_t MaxParameters = 15; 232360784Sdim 233360784Sdim support::ulittle32_t ExceptionCode; 234360784Sdim support::ulittle32_t ExceptionFlags; 235360784Sdim support::ulittle64_t ExceptionRecord; 236360784Sdim support::ulittle64_t ExceptionAddress; 237360784Sdim support::ulittle32_t NumberParameters; 238360784Sdim support::ulittle32_t UnusedAlignment; 239360784Sdim support::ulittle64_t ExceptionInformation[MaxParameters]; 240360784Sdim}; 241360784Sdimstatic_assert(sizeof(Exception) == 152, ""); 242360784Sdim 243360784Sdimstruct ExceptionStream { 244360784Sdim support::ulittle32_t ThreadId; 245360784Sdim support::ulittle32_t UnusedAlignment; 246360784Sdim Exception ExceptionRecord; 247360784Sdim LocationDescriptor ThreadContext; 248360784Sdim}; 249360784Sdimstatic_assert(sizeof(ExceptionStream) == 168, ""); 250360784Sdim 251351278Sdim} // namespace minidump 252351278Sdim 253351278Sdimtemplate <> struct DenseMapInfo<minidump::StreamType> { 254351278Sdim static minidump::StreamType getEmptyKey() { return minidump::StreamType(-1); } 255351278Sdim 256351278Sdim static minidump::StreamType getTombstoneKey() { 257351278Sdim return minidump::StreamType(-2); 258351278Sdim } 259351278Sdim 260351278Sdim static unsigned getHashValue(minidump::StreamType Val) { 261351278Sdim return DenseMapInfo<uint32_t>::getHashValue(static_cast<uint32_t>(Val)); 262351278Sdim } 263351278Sdim 264351278Sdim static bool isEqual(minidump::StreamType LHS, minidump::StreamType RHS) { 265351278Sdim return LHS == RHS; 266351278Sdim } 267351278Sdim}; 268351278Sdim 269351278Sdim} // namespace llvm 270351278Sdim 271351278Sdim#endif // LLVM_BINARYFORMAT_MINIDUMP_H 272