18template <
typename EndianType>
19static inline void mapOptional(yaml::IO &IO,
const char *Key, EndianType &Val,
20 typename EndianType::value_type
Default) {
21 IO.mapOptional(Key, Val, EndianType(
Default));
25template <
typename MapType,
typename EndianType>
28 MapType Mapped =
static_cast<typename EndianType::value_type
>(Val);
29 IO.mapRequired(Key, Mapped);
30 Val =
static_cast<typename EndianType::value_type
>(Mapped);
35template <
typename MapType,
typename EndianType>
36static inline void mapOptionalAs(yaml::IO &IO,
const char *Key, EndianType &Val,
38 MapType Mapped =
static_cast<typename EndianType::value_type
>(Val);
39 IO.mapOptional(Key, Mapped,
Default);
40 Val =
static_cast<typename EndianType::value_type
>(Mapped);
45template <
typename EndianType>
struct HexType;
46template <>
struct HexType<support::
ulittle16_t> {
using type = yaml::Hex16; };
47template <>
struct HexType<support::
ulittle32_t> {
using type = yaml::Hex32; };
48template <>
struct HexType<support::
ulittle64_t> {
using type = yaml::Hex64; };
52template <
typename EndianType>
55 mapRequiredAs<typename HexType<EndianType>::type>(IO, Key, Val);
60template <
typename EndianType>
63 typename EndianType::value_type
Default) {
64 mapOptionalAs<typename HexType<EndianType>::type>(IO, Key, Val,
Default);
71 case StreamType::Exception:
73 case StreamType::MemoryInfoList:
75 case StreamType::MemoryList:
77 case StreamType::Memory64List:
79 case StreamType::ModuleList:
81 case StreamType::SystemInfo:
83 case StreamType::LinuxCPUInfo:
84 case StreamType::LinuxProcStatus:
85 case StreamType::LinuxLSBRelease:
86 case StreamType::LinuxCMDLine:
87 case StreamType::LinuxMaps:
88 case StreamType::LinuxProcStat:
89 case StreamType::LinuxProcUptime:
91 case StreamType::ThreadList:
102 return std::make_unique<ExceptionStream>();
104 return std::make_unique<MemoryInfoListStream>();
106 return std::make_unique<MemoryListStream>();
108 return std::make_unique<Memory64ListStream>();
110 return std::make_unique<ModuleListStream>();
112 return std::make_unique<RawContentStream>(
Type);
114 return std::make_unique<SystemInfoStream>();
116 return std::make_unique<TextContentStream>(
Type);
118 return std::make_unique<ThreadListStream>();
123void yaml::ScalarBitSetTraits<MemoryProtection>::bitset(
125#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME) \
126 IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);
127#include "llvm/BinaryFormat/MinidumpConstants.def"
130void yaml::ScalarBitSetTraits<MemoryState>::bitset(IO &IO,
MemoryState &State) {
131#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME) \
132 IO.bitSetCase(State, #NATIVENAME, MemoryState::NAME);
133#include "llvm/BinaryFormat/MinidumpConstants.def"
136void yaml::ScalarBitSetTraits<MemoryType>::bitset(IO &IO,
MemoryType &
Type) {
137#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME) \
138 IO.bitSetCase(Type, #NATIVENAME, MemoryType::NAME);
139#include "llvm/BinaryFormat/MinidumpConstants.def"
142void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
144#define HANDLE_MDMP_ARCH(CODE, NAME) \
145 IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
146#include "llvm/BinaryFormat/MinidumpConstants.def"
147 IO.enumFallback<Hex16>(Arch);
150void yaml::ScalarEnumerationTraits<OSPlatform>::enumeration(IO &IO,
152#define HANDLE_MDMP_PLATFORM(CODE, NAME) \
153 IO.enumCase(Plat, #NAME, OSPlatform::NAME);
154#include "llvm/BinaryFormat/MinidumpConstants.def"
155 IO.enumFallback<Hex32>(Plat);
158void yaml::ScalarEnumerationTraits<StreamType>::enumeration(IO &IO,
160#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) \
161 IO.enumCase(Type, #NAME, StreamType::NAME);
162#include "llvm/BinaryFormat/MinidumpConstants.def"
163 IO.enumFallback<Hex32>(
Type);
173template <std::
size_t N>
struct FixedSizeHex {
174 FixedSizeHex(
uint8_t (&Storage)[
N]) : Storage(Storage) {}
182template <std::
size_t N>
struct ScalarTraits<FixedSizeHex<
N>> {
189 return "Invalid hex digit in input";
190 if (Scalar.size() < 2 *
N)
191 return "String too short";
192 if (Scalar.size() > 2 *
N)
193 return "String too long";
204 FixedSizeHex<
sizeof(
Info.ProcessorFeatures)> Features(
Info.ProcessorFeatures);
205 IO.mapRequired(
"Features", Features);
210template <std::
size_t N>
struct FixedSizeString {
211 FixedSizeString(
char (&Storage)[
N]) : Storage(Storage) {}
219template <std::
size_t N>
struct ScalarTraits<FixedSizeString<
N>> {
225 if (Scalar.size() <
N)
226 return "String too short";
227 if (Scalar.size() >
N)
228 return "String too long";
240 FixedSizeString<
sizeof(
Info.VendorID)> VendorID(
Info.VendorID);
241 IO.mapRequired(
"Vendor ID", VendorID);
251 mapRequiredAs<MemoryProtection>(IO,
"Allocation Protect",
252 Info.AllocationProtect);
255 mapRequiredAs<MemoryState>(IO,
"State",
Info.State);
256 mapOptionalAs<MemoryProtection>(IO,
"Protect",
Info.Protect,
257 Info.AllocationProtect);
258 mapRequiredAs<MemoryType>(IO,
"Type",
Info.Type);
264 MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
290 mapOptional(IO,
"Time Date Stamp",
M.Entry.TimeDateStamp, 0);
291 IO.mapRequired(
"Module Name",
M.Name);
293 IO.mapRequired(
"CodeView Record",
M.CvRecord);
300 IO.mapOptional(
"Content",
Stream.Content);
301 IO.mapOptional(
"Size",
Stream.Size,
Stream.Content.binary_size());
306 return "Stream size must be greater or equal to the content size";
312 MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
317 IO.mapRequired(
"Memory Ranges",
Stream.Infos);
321 IO.mapRequired(
"Memory Ranges",
Stream.Entries);
325 IO.mapRequired(
"Memory Ranges",
Stream.Entries);
329 for (
auto &Entry :
Stream.Entries) {
330 if (Entry.Entry.DataSize < Entry.Content.binary_size())
331 return "Memory region size must be greater or equal to the content size";
337 IO.mapRequired(
"Modules",
Stream.Entries);
342 IO.mapRequired(
"Processor Arch",
Info.ProcessorArch);
345 IO.mapOptional(
"Number of Processors",
Info.NumberOfProcessors, 0);
346 IO.mapOptional(
"Product type",
Info.ProductType, 0);
350 IO.mapRequired(
"Platform ID",
Info.PlatformId);
351 IO.mapOptional(
"CSD Version",
Stream.CSDVersion,
"");
355 case ProcessorArchitecture::X86:
356 case ProcessorArchitecture::AMD64:
357 IO.mapOptional(
"CPU",
Info.CPU.X86);
359 case ProcessorArchitecture::ARM:
360 case ProcessorArchitecture::ARM64:
361 case ProcessorArchitecture::BP_ARM64:
362 IO.mapOptional(
"CPU",
Info.CPU.Arm);
365 IO.mapOptional(
"CPU",
Info.CPU.Other);
371 IO.mapOptional(
"Text",
Stream.Text);
374void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
377 IO.mapRequired(
"Content",
Content);
380void yaml::MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
383 IO.mapRequired(
"Content",
Content);
394 IO.mapRequired(
"Context",
T.Context);
395 IO.mapRequired(
"Stack",
T.Entry.Stack,
T.Stack);
399 IO.mapRequired(
"Threads",
Stream.Entries);
404 IO.mapRequired(
"Exception Record",
Stream.MDExceptionStream.ExceptionRecord);
405 IO.mapRequired(
"Thread Context",
Stream.ThreadContext);
429 yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
433 IO.mapRequired(
"Type",
Type);
435 if (!IO.outputting())
439 streamMapping(IO, llvm::cast<MinidumpYAML::ExceptionStream>(*S));
469 yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
488 IO.mapTag(
"!minidump",
true);
492 IO.mapRequired(
"Streams",
O.Streams);
501 File.getExceptionStream(StreamDesc);
502 if (!ExpectedExceptionStream)
503 return ExpectedExceptionStream.
takeError();
505 File.getRawData(ExpectedExceptionStream->ThreadContext);
506 if (!ExpectedThreadContext)
507 return ExpectedThreadContext.
takeError();
508 return std::make_unique<ExceptionStream>(*ExpectedExceptionStream,
509 *ExpectedThreadContext);
512 if (
auto ExpectedList = File.getMemoryInfoList())
513 return std::make_unique<MemoryInfoListStream>(*ExpectedList);
515 return ExpectedList.takeError();
518 auto ExpectedList = File.getMemoryList();
520 return ExpectedList.takeError();
521 std::vector<MemoryListStream::entry_type> Ranges;
523 auto ExpectedContent = File.getRawData(MD.Memory);
524 if (!ExpectedContent)
525 return ExpectedContent.takeError();
526 Ranges.push_back({MD, *ExpectedContent});
528 return std::make_unique<MemoryListStream>(std::move(Ranges));
533 std::vector<Memory64ListStream::entry_type> Ranges;
535 Ranges.push_back({Pair.first, Pair.second});
540 return std::make_unique<Memory64ListStream>(std::move(Ranges));
543 auto ExpectedList = File.getModuleList();
545 return ExpectedList.takeError();
546 std::vector<ModuleListStream::entry_type> Modules;
547 for (
const Module &M : *ExpectedList) {
548 auto ExpectedName = File.getString(M.ModuleNameRVA);
550 return ExpectedName.takeError();
551 auto ExpectedCv = File.getRawData(M.CvRecord);
553 return ExpectedCv.takeError();
554 auto ExpectedMisc = File.getRawData(M.MiscRecord);
556 return ExpectedMisc.takeError();
558 {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});
560 return std::make_unique<ModuleListStream>(std::move(Modules));
563 return std::make_unique<RawContentStream>(StreamDesc.
Type,
564 File.getRawStream(StreamDesc));
566 auto ExpectedInfo = File.getSystemInfo();
568 return ExpectedInfo.takeError();
569 auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);
570 if (!ExpectedCSDVersion)
571 return ExpectedInfo.takeError();
572 return std::make_unique<SystemInfoStream>(*ExpectedInfo,
573 std::move(*ExpectedCSDVersion));
576 return std::make_unique<TextContentStream>(
577 StreamDesc.
Type, toStringRef(File.getRawStream(StreamDesc)));
579 auto ExpectedList = File.getThreadList();
581 return ExpectedList.takeError();
582 std::vector<ThreadListStream::entry_type> Threads;
583 for (
const Thread &
T : *ExpectedList) {
584 auto ExpectedStack = File.getRawData(
T.Stack.Memory);
586 return ExpectedStack.takeError();
587 auto ExpectedContext = File.getRawData(
T.Context);
588 if (!ExpectedContext)
589 return ExpectedContext.takeError();
590 Threads.push_back({
T, *ExpectedStack, *ExpectedContext});
592 return std::make_unique<ThreadListStream>(std::move(Threads));
599 std::vector<std::unique_ptr<Stream>>
Streams;
600 Streams.reserve(File.streams().size());
601 for (
const Directory &StreamDesc : File.streams()) {
604 return ExpectedStream.takeError();
605 Streams.push_back(std::move(*ExpectedStream));
Analysis containing CSE Info
static void mapOptionalHex(yaml::IO &IO, const char *Key, EndianType &Val, typename EndianType::value_type Default)
Perform an optional yaml-mapping of an endian-aware type as an appropriately-sized hex value.
static void mapRequiredAs(yaml::IO &IO, const char *Key, EndianType &Val)
Yaml-map an endian-aware type EndianType as some other type MapType.
static std::string streamValidate(RawContentStream &Stream)
static void mapOptionalAs(yaml::IO &IO, const char *Key, EndianType &Val, MapType Default)
Perform an optional yaml-mapping of an endian-aware type EndianType as some other type MapType.
static void mapRequiredHex(yaml::IO &IO, const char *Key, EndianType &Val)
Yaml-map an endian-aware type as an appropriately-sized hex value.
static void streamMapping(yaml::IO &IO, RawContentStream &Stream)
static void mapOptional(yaml::IO &IO, const char *Key, EndianType &Val, typename EndianType::value_type Default)
Perform an optional yaml-mapping of an endian-aware type EndianType.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static bool isHexDigit(const char C)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
A Module instance is used to store all the information related to an LLVM module.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
The instances of the Type class are immutable: once they are created, they are never changed.
Type(LLVMContext &C, TypeID tid)
A class providing access to the contents of a minidump file.
This class implements an extremely fast bulk output stream that can only output to a stream.
This class provides various memory handling functions that manipulate MemoryBlock instances.
Specialized YAMLIO scalar type for representing a binary blob.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ProcessorArchitecture
The processor architecture of the system that generated this minidump.
StreamType
The type of a minidump stream identifies its contents.
OSPlatform
The OS Platform of the system that generated this minidump.
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
detail::packed_endian_specific_integral< uint64_t, llvm::endianness::little, unaligned > ulittle64_t
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
OutputIt copy(R &&Range, OutputIt Out)
ExceptionStream minidump stream.
A structure containing the list of MemoryInfo entries comprising a MemoryInfoList stream.
The top level structure representing a minidump object, consisting of a minidump header,...
std::vector< std::unique_ptr< Stream > > Streams
The list of streams in this minidump object.
static Expected< Object > create(const object::MinidumpFile &File)
A minidump stream represented as a sequence of hex bytes.
The base class for all minidump streams.
static std::unique_ptr< Stream > create(minidump::StreamType Type)
Create an empty stream of the given Type.
static StreamKind getKind(minidump::StreamType Type)
Get the stream Kind used for representing streams of a given Type.
SystemInfo minidump stream.
A StringRef, which is printed using YAML block notation.
A stream representing a list of abstract entries in a minidump stream.
minidump::MemoryDescriptor_64 Entry
Specifies the location and type of a single stream in the minidump file.
support::little_t< StreamType > Type
static constexpr size_t MaxParameters
support::ulittle32_t ExceptionFlags
support::ulittle32_t NumberParameters
support::ulittle64_t ExceptionInformation[MaxParameters]
support::ulittle64_t ExceptionRecord
support::ulittle64_t ExceptionAddress
support::ulittle32_t ExceptionCode
Describes a single memory range (both its VM address and where to find it in the file) of the process...
The SystemInfo stream, containing various information about the system where this minidump was genera...
Describes a single thread in the minidump file.
static QuotingType mustQuote(StringRef S)
static StringRef input(StringRef Scalar, void *, FixedSizeHex< N > &Fixed)
static void output(const FixedSizeHex< N > &Fixed, void *, raw_ostream &OS)
static QuotingType mustQuote(StringRef S)
static StringRef input(StringRef Scalar, void *, FixedSizeString< N > &Fixed)
static void output(const FixedSizeString< N > &Fixed, void *, raw_ostream &OS)