#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 {
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();
const StreamKind Kind;
const minidump::StreamType Type;
static StreamKind getKind(minidump::StreamType Type);
static std::unique_ptr<Stream> create(minidump::StreamType Type);
static Expected<std::unique_ptr<Stream>>
create(const minidump::Directory &StreamDesc,
const object::MinidumpFile &File);
};
namespace detail {
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; }
};
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;
};
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;
};
struct ParsedMemoryDescriptor {
static constexpr Stream::StreamKind Kind = Stream::StreamKind::MemoryList;
static constexpr minidump::StreamType Type = minidump::StreamType::MemoryList;
minidump::MemoryDescriptor Entry;
yaml::BinaryRef Content;
};
}
using ModuleListStream = detail::ListStream<detail::ParsedModule>;
using ThreadListStream = detail::ListStream<detail::ParsedThread>;
using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
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;
}
};
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;
}
};
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;
}
};
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;
}
};
LLVM_YAML_STRONG_TYPEDEF(StringRef, BlockStringRef)
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;
}
};
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)) {}
minidump::Header Header;
std::vector<std::unique_ptr<Stream>> Streams;
static Expected<Object> create(const object::MinidumpFile &File);
};
}
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);
};
}
}
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