Viewing file: MinidumpYAML.h (9.75 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
//===- MinidumpYAML.h - Minidump YAMLIO implementation ----------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECTYAML_MINIDUMPYAML_H #define LLVM_OBJECTYAML_MINIDUMPYAML_H
#include "llvm/BinaryFormat/Minidump.h" #include "llvm/Object/Minidump.h" #include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/YAMLTraits.h"
namespace llvm { namespace MinidumpYAML {
/// The base class for all minidump streams. The "Type" of the stream /// corresponds to the Stream Type field in the minidump file. The "Kind" field /// specifies how are we going to treat it. For highly specialized streams (e.g. /// SystemInfo), there is a 1:1 mapping between Types and Kinds, but in general /// one stream Kind can be used to represent multiple stream Types (e.g. any /// unrecognised stream Type will be handled via RawContentStream). The mapping /// from Types to Kinds is fixed and given by the static getKind function. struct Stream { enum class StreamKind { Exception, MemoryInfoList, MemoryList, ModuleList, RawContent, SystemInfo, TextContent, ThreadList, };
Stream(StreamKind Kind, minidump::StreamType Type) : Kind(Kind), Type(Type) {} virtual ~Stream(); // anchor
const StreamKind Kind; const minidump::StreamType Type;
/// Get the stream Kind used for representing streams of a given Type. static StreamKind getKind(minidump::StreamType Type);
/// Create an empty stream of the given Type. static std::unique_ptr<Stream> create(minidump::StreamType Type);
/// Create a stream from the given stream directory entry. static Expected<std::unique_ptr<Stream>> create(const minidump::Directory &StreamDesc, const object::MinidumpFile &File); };
namespace detail { /// A stream representing a list of abstract entries in a minidump stream. Its /// instantiations can be used to represent the ModuleList stream and other /// streams with a similar structure. template <typename EntryT> struct ListStream : public Stream { using entry_type = EntryT;
std::vector<entry_type> Entries;
explicit ListStream(std::vector<entry_type> Entries = {}) : Stream(EntryT::Kind, EntryT::Type), Entries(std::move(Entries)) {}
static bool classof(const Stream *S) { return S->Kind == EntryT::Kind; } };
/// A structure containing all data belonging to a single minidump module. struct ParsedModule { static constexpr Stream::StreamKind Kind = Stream::StreamKind::ModuleList; static constexpr minidump::StreamType Type = minidump::StreamType::ModuleList;
minidump::Module Entry; std::string Name; yaml::BinaryRef CvRecord; yaml::BinaryRef MiscRecord; };
/// A structure containing all data belonging to a single minidump thread. struct ParsedThread { static constexpr Stream::StreamKind Kind = Stream::StreamKind::ThreadList; static constexpr minidump::StreamType Type = minidump::StreamType::ThreadList;
minidump::Thread Entry; yaml::BinaryRef Stack; yaml::BinaryRef Context; };
/// A structure containing all data describing a single memory region. struct ParsedMemoryDescriptor { static constexpr Stream::StreamKind Kind = Stream::StreamKind::MemoryList; static constexpr minidump::StreamType Type = minidump::StreamType::MemoryList;
minidump::MemoryDescriptor Entry; yaml::BinaryRef Content; }; } // namespace detail
using ModuleListStream = detail::ListStream<detail::ParsedModule>; using ThreadListStream = detail::ListStream<detail::ParsedThread>; using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
/// ExceptionStream minidump stream. struct ExceptionStream : public Stream { minidump::ExceptionStream MDExceptionStream; yaml::BinaryRef ThreadContext;
ExceptionStream() : Stream(StreamKind::Exception, minidump::StreamType::Exception), MDExceptionStream({}) {}
explicit ExceptionStream(const minidump::ExceptionStream &MDExceptionStream, ArrayRef<uint8_t> ThreadContext) : Stream(StreamKind::Exception, minidump::StreamType::Exception), MDExceptionStream(MDExceptionStream), ThreadContext(ThreadContext) {}
static bool classof(const Stream *S) { return S->Kind == StreamKind::Exception; } };
/// A structure containing the list of MemoryInfo entries comprising a /// MemoryInfoList stream. struct MemoryInfoListStream : public Stream { std::vector<minidump::MemoryInfo> Infos;
MemoryInfoListStream() : Stream(StreamKind::MemoryInfoList, minidump::StreamType::MemoryInfoList) {}
explicit MemoryInfoListStream( iterator_range<object::MinidumpFile::MemoryInfoIterator> Range) : Stream(StreamKind::MemoryInfoList, minidump::StreamType::MemoryInfoList), Infos(Range.begin(), Range.end()) {}
static bool classof(const Stream *S) { return S->Kind == StreamKind::MemoryInfoList; } };
/// A minidump stream represented as a sequence of hex bytes. This is used as a /// fallback when no other stream kind is suitable. struct RawContentStream : public Stream { yaml::BinaryRef Content; yaml::Hex32 Size;
RawContentStream(minidump::StreamType Type, ArrayRef<uint8_t> Content = {}) : Stream(StreamKind::RawContent, Type), Content(Content), Size(Content.size()) {}
static bool classof(const Stream *S) { return S->Kind == StreamKind::RawContent; } };
/// SystemInfo minidump stream. struct SystemInfoStream : public Stream { minidump::SystemInfo Info; std::string CSDVersion;
SystemInfoStream() : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo) { memset(&Info, 0, sizeof(Info)); }
explicit SystemInfoStream(const minidump::SystemInfo &Info, std::string CSDVersion) : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo), Info(Info), CSDVersion(std::move(CSDVersion)) {}
static bool classof(const Stream *S) { return S->Kind == StreamKind::SystemInfo; } };
/// A StringRef, which is printed using YAML block notation. LLVM_YAML_STRONG_TYPEDEF(StringRef, BlockStringRef)
/// A minidump stream containing textual data (typically, the contents of a /// /proc/<pid> file on linux). struct TextContentStream : public Stream { BlockStringRef Text;
TextContentStream(minidump::StreamType Type, StringRef Text = {}) : Stream(StreamKind::TextContent, Type), Text(Text) {}
static bool classof(const Stream *S) { return S->Kind == StreamKind::TextContent; } };
/// The top level structure representing a minidump object, consisting of a /// minidump header, and zero or more streams. To construct an Object from a /// minidump file, use the static create function. To serialize to/from yaml, /// use the appropriate streaming operator on a yaml stream. struct Object { Object() = default; Object(const Object &) = delete; Object &operator=(const Object &) = delete; Object(Object &&) = default; Object &operator=(Object &&) = default;
Object(const minidump::Header &Header, std::vector<std::unique_ptr<Stream>> Streams) : Header(Header), Streams(std::move(Streams)) {}
/// The minidump header. minidump::Header Header;
/// The list of streams in this minidump object. std::vector<std::unique_ptr<Stream>> Streams;
static Expected<Object> create(const object::MinidumpFile &File); };
} // namespace MinidumpYAML
namespace yaml { template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> { static void output(const MinidumpYAML::BlockStringRef &Text, void *, raw_ostream &OS) { OS << Text; }
static StringRef input(StringRef Scalar, void *, MinidumpYAML::BlockStringRef &Text) { Text = Scalar; return ""; } };
template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> { static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S); static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S); };
template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> { static void mapping(IO &IO, minidump::MemoryDescriptor &Memory, BinaryRef &Content); };
} // namespace yaml
} // namespace llvm
LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryProtection) LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryState) LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryType)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform) LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo) LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo) LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info) LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::Exception) LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryInfo) LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS( llvm::MinidumpYAML::MemoryListStream::entry_type) LLVM_YAML_DECLARE_MAPPING_TRAITS( llvm::MinidumpYAML::ModuleListStream::entry_type) LLVM_YAML_DECLARE_MAPPING_TRAITS( llvm::MinidumpYAML::ThreadListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MinidumpYAML::Stream>) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
#endif // LLVM_OBJECTYAML_MINIDUMPYAML_H
|