- //===- 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 
-