LLVM: lib/ObjectYAML/MinidumpYAML.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
11using namespace llvm;
14
15
16
17
18template
20 typename EndianType::value_type Default) {
22}
23
24
25template <typename MapType, typename EndianType>
27 EndianType &Val) {
28 MapType Mapped = static_cast<typename EndianType::value_type>(Val);
30 Val = static_cast<typename EndianType::value_type>(Mapped);
31}
32
33
34
35template <typename MapType, typename EndianType>
38 MapType Mapped = static_cast<typename EndianType::value_type>(Val);
40 Val = static_cast<typename EndianType::value_type>(Mapped);
41}
42
43namespace {
44
45template 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; };
49}
50
51
52template
54 EndianType &Val) {
56}
57
58
59
60template
62 EndianType &Val,
63 typename EndianType::value_type Default) {
65}
66
68
70 switch (Type) {
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:
93 default:
95 }
96}
97
100 switch (Kind) {
102 return std::make_unique();
104 return std::make_unique();
106 return std::make_unique();
108 return std::make_unique();
110 return std::make_unique();
112 return std::make_unique(Type);
114 return std::make_unique();
116 return std::make_unique(Type);
118 return std::make_unique();
119 }
121}
122
125#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME) \
126 IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);
127#include "llvm/BinaryFormat/MinidumpConstants.def"
128}
129
131#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME) \
132 IO.bitSetCase(State, #NATIVENAME, MemoryState::NAME);
133#include "llvm/BinaryFormat/MinidumpConstants.def"
134}
135
137#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME) \
138 IO.bitSetCase(Type, #NATIVENAME, MemoryType::NAME);
139#include "llvm/BinaryFormat/MinidumpConstants.def"
140}
141
142void yaml::ScalarEnumerationTraits::enumeration(
144#define HANDLE_MDMP_ARCH(CODE, NAME) \
145 IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
146#include "llvm/BinaryFormat/MinidumpConstants.def"
147 IO.enumFallback(Arch);
148}
149
150void yaml::ScalarEnumerationTraits::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(Plat);
156}
157
158void yaml::ScalarEnumerationTraits::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(Type);
164}
165
166void yaml::MappingTraitsCPUInfo::ArmInfo::mapping(IO &IO,
167 CPUInfo::ArmInfo &Info) {
170}
171
172namespace {
173template <std::size_t N> struct FixedSizeHex {
174 FixedSizeHex(uint8_t (&Storage)[N]) : Storage(Storage) {}
175
176 uint8_t (&Storage)[N];
177};
178}
179
180namespace llvm {
181namespace yaml {
182template <std::size_t N> struct ScalarTraits<FixedSizeHex<N>> {
186
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";
195 return "";
196 }
197
199};
200}
201}
202void yaml::MappingTraitsCPUInfo::OtherInfo::mapping(
203 IO &IO, CPUInfo::OtherInfo &Info) {
204 FixedSizeHex<sizeof(Info.ProcessorFeatures)> Features(Info.ProcessorFeatures);
205 IO.mapRequired("Features", Features);
206}
207
208namespace {
209
210template <std::size_t N> struct FixedSizeString {
211 FixedSizeString(char (&Storage)[N]) : Storage(Storage) {}
212
213 char (&Storage)[N];
214};
215}
216
217namespace llvm {
218namespace yaml {
219template <std::size_t N> struct ScalarTraits<FixedSizeString<N>> {
223
226 return "String too short";
228 return "String too long";
230 return "";
231 }
232
234};
235}
236}
237
238void yaml::MappingTraitsCPUInfo::X86Info::mapping(IO &IO,
239 CPUInfo::X86Info &Info) {
240 FixedSizeString<sizeof(Info.VendorID)> VendorID(Info.VendorID);
241 IO.mapRequired("Vendor ID", VendorID);
242
245 mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);
246}
247
248void yaml::MappingTraits::mapping(IO &IO, MemoryInfo &Info) {
252 Info.AllocationProtect);
257 Info.AllocationProtect);
260}
261
262void yaml::MappingTraitsMemory64ListStream::entry\_type::mapping(
263 IO &IO, Memory64ListStream::entry_type &Mem) {
264 MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
266}
267
268void yaml::MappingTraits::mapping(IO &IO,
269 VSFixedFileInfo &Info) {
274 mapOptionalHex(IO, "Product Version High", Info.ProductVersionHigh, 0);
275 mapOptionalHex(IO, "Product Version Low", Info.ProductVersionLow, 0);
283}
284
285void yaml::MappingTraitsModuleListStream::entry\_type::mapping(
287 mapRequiredHex(IO, "Base of Image", M.Entry.BaseOfImage);
288 mapRequiredHex(IO, "Size of Image", M.Entry.SizeOfImage);
290 mapOptional(IO, "Time Date Stamp", M.Entry.TimeDateStamp, 0);
291 IO.mapRequired("Module Name", M.Name);
292 IO.mapOptional("Version Info", M.Entry.VersionInfo, VSFixedFileInfo());
293 IO.mapRequired("CodeView Record", M.CvRecord);
294 IO.mapOptional("Misc Record", M.MiscRecord, yaml::BinaryRef());
297}
298
303
305 if (Stream.Size.value < Stream.Content.binary_size())
306 return "Stream size must be greater or equal to the content size";
307 return "";
308}
309
310void yaml::MappingTraitsMemoryListStream::entry\_type::mapping(
312 MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
314}
315
319
323
327
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";
332 }
333 return "";
334}
335
338}
339
343 mapOptional(IO, "Processor Level", Info.ProcessorLevel, 0);
344 mapOptional(IO, "Processor Revision", Info.ProcessorRevision, 0);
345 IO.mapOptional("Number of Processors", Info.NumberOfProcessors, 0);
355 case ProcessorArchitecture::X86:
356 case ProcessorArchitecture::AMD64:
358 break;
359 case ProcessorArchitecture::ARM:
360 case ProcessorArchitecture::ARM64:
361 case ProcessorArchitecture::BP_ARM64:
363 break;
364 default:
366 break;
367 }
368}
369
373
374void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
375 IO &IO, MemoryDescriptor &Memory, BinaryRef &Content) {
376 mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);
377 IO.mapRequired("Content", Content);
378}
379
380void yaml::MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
381 IO &IO, MemoryDescriptor_64 &Memory, BinaryRef &Content) {
382 mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);
383 IO.mapRequired("Content", Content);
384 mapOptional(IO, "Data Size", Memory.DataSize, Content.binary_size());
385}
386
387void yaml::MappingTraitsThreadListStream::entry\_type::mapping(
390 mapOptionalHex(IO, "Suspend Count", T.Entry.SuspendCount, 0);
391 mapOptionalHex(IO, "Priority Class", T.Entry.PriorityClass, 0);
393 mapOptionalHex(IO, "Environment Block", T.Entry.EnvironmentBlock, 0);
394 IO.mapRequired("Context", T.Context);
395 IO.mapRequired("Stack", T.Entry.Stack, T.Stack);
396}
397
400}
401
404 IO.mapRequired("Exception Record", Stream.MDExceptionStream.ExceptionRecord);
406}
407
408void yaml::MappingTraitsminidump::Exception::mapping(
409 yaml::IO &IO, minidump::Exception &Exception) {
415
417 SmallString<16> Name("Parameter ");
418 Twine(Index).toVector(Name);
420
421 if (Index < Exception.NumberParameters)
423 else
425 }
426}
427
428void yaml::MappingTraits<std::unique_ptr>::mapping(
429 yaml::IO &IO, std::unique_ptrMinidumpYAML::Stream &S) {
432 Type = S->Type;
434
437 switch (S->Kind) {
438 case MinidumpYAML::Stream::StreamKind::Exception:
440 break;
441 case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
443 break;
444 case MinidumpYAML::Stream::StreamKind::MemoryList:
446 break;
447 case MinidumpYAML::Stream::StreamKind::Memory64List:
449 break;
450 case MinidumpYAML::Stream::StreamKind::ModuleList:
452 break;
453 case MinidumpYAML::Stream::StreamKind::RawContent:
455 break;
456 case MinidumpYAML::Stream::StreamKind::SystemInfo:
458 break;
459 case MinidumpYAML::Stream::StreamKind::TextContent:
461 break;
462 case MinidumpYAML::Stream::StreamKind::ThreadList:
464 break;
465 }
466}
467
468std::string yaml::MappingTraits<std::unique_ptr>::validate(
469 yaml::IO &IO, std::unique_ptrMinidumpYAML::Stream &S) {
470 switch (S->Kind) {
471 case MinidumpYAML::Stream::StreamKind::RawContent:
473 case MinidumpYAML::Stream::StreamKind::Memory64List:
475 case MinidumpYAML::Stream::StreamKind::Exception:
476 case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
477 case MinidumpYAML::Stream::StreamKind::MemoryList:
478 case MinidumpYAML::Stream::StreamKind::ModuleList:
479 case MinidumpYAML::Stream::StreamKind::SystemInfo:
480 case MinidumpYAML::Stream::StreamKind::TextContent:
481 case MinidumpYAML::Stream::StreamKind::ThreadList:
482 return "";
483 }
485}
486
487void yaml::MappingTraits::mapping(IO &IO, Object &O) {
488 IO.mapTag("!minidump", true);
489 mapOptionalHex(IO, "Signature", O.Header.Signature, Header::MagicSignature);
490 mapOptionalHex(IO, "Version", O.Header.Version, Header::MagicVersion);
492 IO.mapRequired("Streams", O.Streams);
493}
494
495Expected<std::unique_ptr>
498 switch (Kind) {
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(*ExpectedExceptionStream,
509 *ExpectedThreadContext);
510 }
512 if (auto ExpectedList = File.getMemoryInfoList())
513 return std::make_unique(*ExpectedList);
514 else
515 return ExpectedList.takeError();
516 }
518 auto ExpectedList = File.getMemoryList();
519 if (!ExpectedList)
520 return ExpectedList.takeError();
521 std::vectorMemoryListStream::entry\_type Ranges;
523 auto ExpectedContent = File.getRawData(MD.Memory);
524 if (!ExpectedContent)
525 return ExpectedContent.takeError();
526 Ranges.push_back({MD, *ExpectedContent});
527 }
528 return std::make_unique(std::move(Ranges));
529 }
532 auto Memory64List = File.getMemory64List(Err);
533 std::vectorMemory64ListStream::entry\_type Ranges;
535 Ranges.push_back({Pair.first, Pair.second});
536 }
537
538 if (Err)
539 return Err;
540 return std::make_unique(std::move(Ranges));
541 }
543 auto ExpectedList = File.getModuleList();
544 if (!ExpectedList)
545 return ExpectedList.takeError();
546 std::vectorModuleListStream::entry\_type Modules;
547 for (const Module &M : *ExpectedList) {
548 auto ExpectedName = File.getString(M.ModuleNameRVA);
549 if (!ExpectedName)
550 return ExpectedName.takeError();
551 auto ExpectedCv = File.getRawData(M.CvRecord);
552 if (!ExpectedCv)
553 return ExpectedCv.takeError();
554 auto ExpectedMisc = File.getRawData(M.MiscRecord);
555 if (!ExpectedMisc)
556 return ExpectedMisc.takeError();
557 Modules.push_back(
558 {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});
559 }
560 return std::make_unique(std::move(Modules));
561 }
563 return std::make_unique(StreamDesc.Type,
564 File.getRawStream(StreamDesc));
566 auto ExpectedInfo = File.getSystemInfo();
567 if (!ExpectedInfo)
568 return ExpectedInfo.takeError();
569 auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);
570 if (!ExpectedCSDVersion)
571 return ExpectedInfo.takeError();
572 return std::make_unique(*ExpectedInfo,
573 std::move(*ExpectedCSDVersion));
574 }
576 return std::make_unique(
577 StreamDesc.Type, toStringRef(File.getRawStream(StreamDesc)));
579 auto ExpectedList = File.getThreadList();
580 if (!ExpectedList)
581 return ExpectedList.takeError();
582 std::vectorThreadListStream::entry\_type Threads;
583 for (const Thread &T : *ExpectedList) {
584 auto ExpectedStack = File.getRawData(T.Stack.Memory);
585 if (!ExpectedStack)
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});
591 }
592 return std::make_unique(std::move(Threads));
593 }
594 }
596}
597
599 std::vector<std::unique_ptr> Streams;
600 Streams.reserve(File.streams().size());
601 for (const Directory &StreamDesc : File.streams()) {
602 auto ExpectedStream = Stream::create(StreamDesc, File);
603 if (!ExpectedStream)
604 return ExpectedStream.takeError();
605 Streams.push_back(std::move(*ExpectedStream));
606 }
607 return Object(File.header(), std::move(Streams));
608}
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.
Definition MinidumpYAML.cpp:61
static void mapRequiredAs(yaml::IO &IO, const char *Key, EndianType &Val)
Yaml-map an endian-aware type EndianType as some other type MapType.
Definition MinidumpYAML.cpp:26
static std::string streamValidate(RawContentStream &Stream)
Definition MinidumpYAML.cpp:304
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.
Definition MinidumpYAML.cpp:36
static void mapRequiredHex(yaml::IO &IO, const char *Key, EndianType &Val)
Yaml-map an endian-aware type as an appropriately-sized hex value.
Definition MinidumpYAML.cpp:53
static void streamMapping(yaml::IO &IO, RawContentStream &Stream)
Definition MinidumpYAML.cpp:299
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.
Definition MinidumpYAML.cpp:19
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
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.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
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.
virtual bool outputting() const =0
void mapOptional(StringRef Key, T &Val)
void mapRequired(StringRef Key, T &Val)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
detail::ListStream< detail::ParsedModule > ModuleListStream
detail::ListStream< detail::ParsedMemoryDescriptor > MemoryListStream
detail::ListStream< detail::ParsedThread > ThreadListStream
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< uint64_t, llvm::endianness::little, unaligned > ulittle64_t
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
QuotingType
Describe which type of quotes should be used when quoting is necessary.
QuotingType needsQuotes(StringRef S, bool ForcePreserveAsString=true)
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.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation. The return string is half the size of ...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
bool isHexDigit(char C)
Checks if character C is a hexadecimal numeric character.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
ExceptionStream minidump stream.
A structure containing the list of MemoryInfo entries comprising a MemoryInfoList stream.
std::vector< std::unique_ptr< Stream > > Streams
The list of streams in this minidump object.
static Expected< Object > create(const object::MinidumpFile &File)
Definition MinidumpYAML.cpp:598
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.
Definition MinidumpYAML.cpp:98
static StreamKind getKind(minidump::StreamType Type)
Get the stream Kind used for representing streams of a given Type.
Definition MinidumpYAML.cpp:69
const minidump::StreamType Type
SystemInfo minidump stream.
A StringRef, which is printed using YAML block notation.
detail::ParsedModule entry_type
std::vector< entry_type > Entries
minidump::MemoryDescriptor_64 Entry
Specifies the location and type of a single stream in the minidump file.
support::little_t< StreamType > Type
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.
This class should be specialized by any integer type that is a union of bit values and the YAML repre...
static QuotingType mustQuote(StringRef S)
Definition MinidumpYAML.cpp:198
static StringRef input(StringRef Scalar, void *, FixedSizeHex< N > &Fixed)
Definition MinidumpYAML.cpp:187
static void output(const FixedSizeHex< N > &Fixed, void *, raw_ostream &OS)
Definition MinidumpYAML.cpp:183
static QuotingType mustQuote(StringRef S)
Definition MinidumpYAML.cpp:233
static StringRef input(StringRef Scalar, void *, FixedSizeString< N > &Fixed)
Definition MinidumpYAML.cpp:224
static void output(const FixedSizeString< N > &Fixed, void *, raw_ostream &OS)
Definition MinidumpYAML.cpp:220
This class should be specialized by type that requires custom conversion to/from a yaml scalar.