19template <
typename EndianType>
20static inline void mapOptional(yaml::IO &IO,
const char *Key, EndianType &Val,
21 typename EndianType::value_type
Default) {
22 IO.mapOptional(Key, Val, EndianType(
Default));
26template <
typename MapType,
typename EndianType>
29 MapType Mapped =
static_cast<typename EndianType::value_type
>(Val);
30 IO.mapRequired(Key, Mapped);
31 Val =
static_cast<typename EndianType::value_type
>(Mapped);
36template <
typename MapType,
typename EndianType>
37static inline void mapOptionalAs(yaml::IO &IO,
const char *Key, EndianType &Val,
39 MapType Mapped =
static_cast<typename EndianType::value_type
>(Val);
40 IO.mapOptional(Key, Mapped,
Default);
41 Val =
static_cast<typename EndianType::value_type
>(Mapped);
46template <
typename EndianType>
struct HexType;
47template <>
struct HexType<support::
ulittle16_t> {
using type = yaml::Hex16; };
48template <>
struct HexType<support::
ulittle32_t> {
using type = yaml::Hex32; };
49template <>
struct HexType<support::
ulittle64_t> {
using type = yaml::Hex64; };
53template <
typename EndianType>
56 mapRequiredAs<typename HexType<EndianType>::type>(IO, Key, Val);
61template <
typename EndianType>
64 typename EndianType::value_type
Default) {
65 mapOptionalAs<typename HexType<EndianType>::type>(IO, Key, Val,
Default);
72 case StreamType::Exception:
74 case StreamType::MemoryInfoList:
76 case StreamType::MemoryList:
78 case StreamType::Memory64List:
80 case StreamType::ModuleList:
82 case StreamType::SystemInfo:
84 case StreamType::LinuxCPUInfo:
85 case StreamType::LinuxProcStatus:
86 case StreamType::LinuxLSBRelease:
87 case StreamType::LinuxCMDLine:
88 case StreamType::LinuxMaps:
89 case StreamType::LinuxProcStat:
90 case StreamType::LinuxProcUptime:
92 case StreamType::ThreadList:
103 return std::make_unique<ExceptionStream>();
105 return std::make_unique<MemoryInfoListStream>();
107 return std::make_unique<MemoryListStream>();
109 return std::make_unique<Memory64ListStream>();
111 return std::make_unique<ModuleListStream>();
113 return std::make_unique<RawContentStream>(
Type);
115 return std::make_unique<SystemInfoStream>();
117 return std::make_unique<TextContentStream>(
Type);
119 return std::make_unique<ThreadListStream>();
124void yaml::ScalarBitSetTraits<MemoryProtection>::bitset(
126#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME) \
127 IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);
128#include "llvm/BinaryFormat/MinidumpConstants.def"
131void yaml::ScalarBitSetTraits<MemoryState>::bitset(IO &IO,
MemoryState &State) {
132#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME) \
133 IO.bitSetCase(State, #NATIVENAME, MemoryState::NAME);
134#include "llvm/BinaryFormat/MinidumpConstants.def"
137void yaml::ScalarBitSetTraits<MemoryType>::bitset(IO &IO,
MemoryType &
Type) {
138#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME) \
139 IO.bitSetCase(Type, #NATIVENAME, MemoryType::NAME);
140#include "llvm/BinaryFormat/MinidumpConstants.def"
143void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
145#define HANDLE_MDMP_ARCH(CODE, NAME) \
146 IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
147#include "llvm/BinaryFormat/MinidumpConstants.def"
148 IO.enumFallback<Hex16>(Arch);
151void yaml::ScalarEnumerationTraits<OSPlatform>::enumeration(IO &IO,
153#define HANDLE_MDMP_PLATFORM(CODE, NAME) \
154 IO.enumCase(Plat, #NAME, OSPlatform::NAME);
155#include "llvm/BinaryFormat/MinidumpConstants.def"
156 IO.enumFallback<Hex32>(Plat);
159void yaml::ScalarEnumerationTraits<StreamType>::enumeration(IO &IO,
161#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) \
162 IO.enumCase(Type, #NAME, StreamType::NAME);
163#include "llvm/BinaryFormat/MinidumpConstants.def"
164 IO.enumFallback<Hex32>(
Type);
174template <std::
size_t N>
struct FixedSizeHex {
175 FixedSizeHex(uint8_t (&Storage)[
N]) : Storage(Storage) {}
177 uint8_t (&Storage)[
N];
183template <std::
size_t N>
struct ScalarTraits<FixedSizeHex<
N>> {
190 return "Invalid hex digit in input";
191 if (Scalar.size() < 2 *
N)
192 return "String too short";
193 if (Scalar.size() > 2 *
N)
194 return "String too long";
205 FixedSizeHex<
sizeof(
Info.ProcessorFeatures)> Features(
Info.ProcessorFeatures);
206 IO.mapRequired(
"Features", Features);
211template <std::
size_t N>
struct FixedSizeString {
212 FixedSizeString(
char (&Storage)[
N]) : Storage(Storage) {}
220template <std::
size_t N>
struct ScalarTraits<FixedSizeString<
N>> {
226 if (Scalar.size() <
N)
227 return "String too short";
228 if (Scalar.size() >
N)
229 return "String too long";
241 FixedSizeString<
sizeof(
Info.VendorID)> VendorID(
Info.VendorID);
242 IO.mapRequired(
"Vendor ID", VendorID);
252 mapRequiredAs<MemoryProtection>(IO,
"Allocation Protect",
253 Info.AllocationProtect);
256 mapRequiredAs<MemoryState>(IO,
"State",
Info.State);
257 mapOptionalAs<MemoryProtection>(IO,
"Protect",
Info.Protect,
258 Info.AllocationProtect);
259 mapRequiredAs<MemoryType>(IO,
"Type",
Info.Type);
265 MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
291 mapOptional(IO,
"Time Date Stamp",
M.Entry.TimeDateStamp, 0);
292 IO.mapRequired(
"Module Name",
M.Name);
294 IO.mapRequired(
"CodeView Record",
M.CvRecord);
301 IO.mapOptional(
"Content",
Stream.Content);
302 IO.mapOptional(
"Size",
Stream.Size,
Stream.Content.binary_size());
307 return "Stream size must be greater or equal to the content size";
313 MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
318 IO.mapRequired(
"Memory Ranges",
Stream.Infos);
322 IO.mapRequired(
"Memory Ranges",
Stream.Entries);
326 IO.mapRequired(
"Memory Ranges",
Stream.Entries);
330 for (
auto &Entry :
Stream.Entries) {
331 if (Entry.Entry.DataSize < Entry.Content.binary_size())
332 return "Memory region size must be greater or equal to the content size";
338 IO.mapRequired(
"Modules",
Stream.Entries);
343 IO.mapRequired(
"Processor Arch",
Info.ProcessorArch);
346 IO.mapOptional(
"Number of Processors",
Info.NumberOfProcessors, 0);
347 IO.mapOptional(
"Product type",
Info.ProductType, 0);
351 IO.mapRequired(
"Platform ID",
Info.PlatformId);
352 IO.mapOptional(
"CSD Version",
Stream.CSDVersion,
"");
356 case ProcessorArchitecture::X86:
357 case ProcessorArchitecture::AMD64:
358 IO.mapOptional(
"CPU",
Info.CPU.X86);
360 case ProcessorArchitecture::ARM:
361 case ProcessorArchitecture::ARM64:
362 case ProcessorArchitecture::BP_ARM64:
363 IO.mapOptional(
"CPU",
Info.CPU.Arm);
366 IO.mapOptional(
"CPU",
Info.CPU.Other);
372 IO.mapOptional(
"Text",
Stream.Text);
375void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
378 IO.mapRequired(
"Content",
Content);
381void yaml::MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
384 IO.mapRequired(
"Content",
Content);
395 IO.mapRequired(
"Context",
T.Context);
396 IO.mapRequired(
"Stack",
T.Entry.Stack,
T.Stack);
400 IO.mapRequired(
"Threads",
Stream.Entries);
405 IO.mapRequired(
"Exception Record",
Stream.MDExceptionStream.ExceptionRecord);
406 IO.mapRequired(
"Thread Context",
Stream.ThreadContext);
430 yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
434 IO.mapRequired(
"Type",
Type);
436 if (!IO.outputting())
440 streamMapping(IO, llvm::cast<MinidumpYAML::ExceptionStream>(*S));
470 yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
489 IO.mapTag(
"!minidump",
true);
493 IO.mapRequired(
"Streams",
O.Streams);
502 File.getExceptionStream();
503 if (!ExpectedExceptionStream)
504 return ExpectedExceptionStream.
takeError();
506 File.getRawData(ExpectedExceptionStream->ThreadContext);
507 if (!ExpectedThreadContext)
508 return ExpectedThreadContext.
takeError();
509 return std::make_unique<ExceptionStream>(*ExpectedExceptionStream,
510 *ExpectedThreadContext);
513 if (
auto ExpectedList = File.getMemoryInfoList())
514 return std::make_unique<MemoryInfoListStream>(*ExpectedList);
516 return ExpectedList.takeError();
519 auto ExpectedList = File.getMemoryList();
521 return ExpectedList.takeError();
522 std::vector<MemoryListStream::entry_type> Ranges;
524 auto ExpectedContent = File.getRawData(MD.Memory);
525 if (!ExpectedContent)
526 return ExpectedContent.takeError();
527 Ranges.push_back({MD, *ExpectedContent});
529 return std::make_unique<MemoryListStream>(std::move(Ranges));
534 std::vector<Memory64ListStream::entry_type> Ranges;
536 Ranges.push_back({Pair.first, Pair.second});
541 return std::make_unique<Memory64ListStream>(std::move(Ranges));
544 auto ExpectedList = File.getModuleList();
546 return ExpectedList.takeError();
547 std::vector<ModuleListStream::entry_type> Modules;
548 for (
const Module &M : *ExpectedList) {
549 auto ExpectedName = File.getString(M.ModuleNameRVA);
551 return ExpectedName.takeError();
552 auto ExpectedCv = File.getRawData(M.CvRecord);
554 return ExpectedCv.takeError();
555 auto ExpectedMisc = File.getRawData(M.MiscRecord);
557 return ExpectedMisc.takeError();
559 {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});
561 return std::make_unique<ModuleListStream>(std::move(Modules));
564 return std::make_unique<RawContentStream>(StreamDesc.
Type,
565 File.getRawStream(StreamDesc));
567 auto ExpectedInfo = File.getSystemInfo();
569 return ExpectedInfo.takeError();
570 auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);
571 if (!ExpectedCSDVersion)
572 return ExpectedInfo.takeError();
573 return std::make_unique<SystemInfoStream>(*ExpectedInfo,
574 std::move(*ExpectedCSDVersion));
577 return std::make_unique<TextContentStream>(
580 auto ExpectedList = File.getThreadList();
582 return ExpectedList.takeError();
583 std::vector<ThreadListStream::entry_type> Threads;
584 for (
const Thread &
T : *ExpectedList) {
585 auto ExpectedStack = File.getRawData(
T.Stack.Memory);
587 return ExpectedStack.takeError();
588 auto ExpectedContext = File.getRawData(
T.Context);
589 if (!ExpectedContext)
590 return ExpectedContext.takeError();
591 Threads.push_back({
T, *ExpectedStack, *ExpectedContext});
593 return std::make_unique<ThreadListStream>(std::move(Threads));
600 std::vector<std::unique_ptr<Stream>>
Streams;
601 Streams.reserve(File.streams().size());
602 for (
const Directory &StreamDesc : File.streams()) {
605 return ExpectedStream.takeError();
606 Streams.push_back(std::move(*ExpectedStream));
This file defines the BumpPtrAllocator interface.
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.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
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)