Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- MinidumpYAML.h - Minidump YAMLIO implementation ----------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_OBJECTYAML_MINIDUMPYAML_H
  10. #define LLVM_OBJECTYAML_MINIDUMPYAML_H
  11.  
  12. #include "llvm/BinaryFormat/Minidump.h"
  13. #include "llvm/Object/Minidump.h"
  14. #include "llvm/ObjectYAML/YAML.h"
  15. #include "llvm/Support/YAMLTraits.h"
  16.  
  17. namespace llvm {
  18. namespace MinidumpYAML {
  19.  
  20. /// The base class for all minidump streams. The "Type" of the stream
  21. /// corresponds to the Stream Type field in the minidump file. The "Kind" field
  22. /// specifies how are we going to treat it. For highly specialized streams (e.g.
  23. /// SystemInfo), there is a 1:1 mapping between Types and Kinds, but in general
  24. /// one stream Kind can be used to represent multiple stream Types (e.g. any
  25. /// unrecognised stream Type will be handled via RawContentStream). The mapping
  26. /// from Types to Kinds is fixed and given by the static getKind function.
  27. struct Stream {
  28.   enum class StreamKind {
  29.     Exception,
  30.     MemoryInfoList,
  31.     MemoryList,
  32.     ModuleList,
  33.     RawContent,
  34.     SystemInfo,
  35.     TextContent,
  36.     ThreadList,
  37.   };
  38.  
  39.   Stream(StreamKind Kind, minidump::StreamType Type) : Kind(Kind), Type(Type) {}
  40.   virtual ~Stream(); // anchor
  41.  
  42.   const StreamKind Kind;
  43.   const minidump::StreamType Type;
  44.  
  45.   /// Get the stream Kind used for representing streams of a given Type.
  46.   static StreamKind getKind(minidump::StreamType Type);
  47.  
  48.   /// Create an empty stream of the given Type.
  49.   static std::unique_ptr<Stream> create(minidump::StreamType Type);
  50.  
  51.   /// Create a stream from the given stream directory entry.
  52.   static Expected<std::unique_ptr<Stream>>
  53.   create(const minidump::Directory &StreamDesc,
  54.          const object::MinidumpFile &File);
  55. };
  56.  
  57. namespace detail {
  58. /// A stream representing a list of abstract entries in a minidump stream. Its
  59. /// instantiations can be used to represent the ModuleList stream and other
  60. /// streams with a similar structure.
  61. template <typename EntryT> struct ListStream : public Stream {
  62.   using entry_type = EntryT;
  63.  
  64.   std::vector<entry_type> Entries;
  65.  
  66.   explicit ListStream(std::vector<entry_type> Entries = {})
  67.       : Stream(EntryT::Kind, EntryT::Type), Entries(std::move(Entries)) {}
  68.  
  69.   static bool classof(const Stream *S) { return S->Kind == EntryT::Kind; }
  70. };
  71.  
  72. /// A structure containing all data belonging to a single minidump module.
  73. struct ParsedModule {
  74.   static constexpr Stream::StreamKind Kind = Stream::StreamKind::ModuleList;
  75.   static constexpr minidump::StreamType Type = minidump::StreamType::ModuleList;
  76.  
  77.   minidump::Module Entry;
  78.   std::string Name;
  79.   yaml::BinaryRef CvRecord;
  80.   yaml::BinaryRef MiscRecord;
  81. };
  82.  
  83. /// A structure containing all data belonging to a single minidump thread.
  84. struct ParsedThread {
  85.   static constexpr Stream::StreamKind Kind = Stream::StreamKind::ThreadList;
  86.   static constexpr minidump::StreamType Type = minidump::StreamType::ThreadList;
  87.  
  88.   minidump::Thread Entry;
  89.   yaml::BinaryRef Stack;
  90.   yaml::BinaryRef Context;
  91. };
  92.  
  93. /// A structure containing all data describing a single memory region.
  94. struct ParsedMemoryDescriptor {
  95.   static constexpr Stream::StreamKind Kind = Stream::StreamKind::MemoryList;
  96.   static constexpr minidump::StreamType Type = minidump::StreamType::MemoryList;
  97.  
  98.   minidump::MemoryDescriptor Entry;
  99.   yaml::BinaryRef Content;
  100. };
  101. } // namespace detail
  102.  
  103. using ModuleListStream = detail::ListStream<detail::ParsedModule>;
  104. using ThreadListStream = detail::ListStream<detail::ParsedThread>;
  105. using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
  106.  
  107. /// ExceptionStream minidump stream.
  108. struct ExceptionStream : public Stream {
  109.   minidump::ExceptionStream MDExceptionStream;
  110.   yaml::BinaryRef ThreadContext;
  111.  
  112.   ExceptionStream()
  113.       : Stream(StreamKind::Exception, minidump::StreamType::Exception),
  114.         MDExceptionStream({}) {}
  115.  
  116.   explicit ExceptionStream(const minidump::ExceptionStream &MDExceptionStream,
  117.                            ArrayRef<uint8_t> ThreadContext)
  118.       : Stream(StreamKind::Exception, minidump::StreamType::Exception),
  119.         MDExceptionStream(MDExceptionStream), ThreadContext(ThreadContext) {}
  120.  
  121.   static bool classof(const Stream *S) {
  122.     return S->Kind == StreamKind::Exception;
  123.   }
  124. };
  125.  
  126. /// A structure containing the list of MemoryInfo entries comprising a
  127. /// MemoryInfoList stream.
  128. struct MemoryInfoListStream : public Stream {
  129.   std::vector<minidump::MemoryInfo> Infos;
  130.  
  131.   MemoryInfoListStream()
  132.       : Stream(StreamKind::MemoryInfoList,
  133.                minidump::StreamType::MemoryInfoList) {}
  134.  
  135.   explicit MemoryInfoListStream(
  136.       iterator_range<object::MinidumpFile::MemoryInfoIterator> Range)
  137.       : Stream(StreamKind::MemoryInfoList,
  138.                minidump::StreamType::MemoryInfoList),
  139.         Infos(Range.begin(), Range.end()) {}
  140.  
  141.   static bool classof(const Stream *S) {
  142.     return S->Kind == StreamKind::MemoryInfoList;
  143.   }
  144. };
  145.  
  146. /// A minidump stream represented as a sequence of hex bytes. This is used as a
  147. /// fallback when no other stream kind is suitable.
  148. struct RawContentStream : public Stream {
  149.   yaml::BinaryRef Content;
  150.   yaml::Hex32 Size;
  151.  
  152.   RawContentStream(minidump::StreamType Type, ArrayRef<uint8_t> Content = {})
  153.       : Stream(StreamKind::RawContent, Type), Content(Content),
  154.         Size(Content.size()) {}
  155.  
  156.   static bool classof(const Stream *S) {
  157.     return S->Kind == StreamKind::RawContent;
  158.   }
  159. };
  160.  
  161. /// SystemInfo minidump stream.
  162. struct SystemInfoStream : public Stream {
  163.   minidump::SystemInfo Info;
  164.   std::string CSDVersion;
  165.  
  166.   SystemInfoStream()
  167.       : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo) {
  168.     memset(&Info, 0, sizeof(Info));
  169.   }
  170.  
  171.   explicit SystemInfoStream(const minidump::SystemInfo &Info,
  172.                             std::string CSDVersion)
  173.       : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
  174.         Info(Info), CSDVersion(std::move(CSDVersion)) {}
  175.  
  176.   static bool classof(const Stream *S) {
  177.     return S->Kind == StreamKind::SystemInfo;
  178.   }
  179. };
  180.  
  181. /// A StringRef, which is printed using YAML block notation.
  182. LLVM_YAML_STRONG_TYPEDEF(StringRef, BlockStringRef)
  183.  
  184. /// A minidump stream containing textual data (typically, the contents of a
  185. /// /proc/<pid> file on linux).
  186. struct TextContentStream : public Stream {
  187.   BlockStringRef Text;
  188.  
  189.   TextContentStream(minidump::StreamType Type, StringRef Text = {})
  190.       : Stream(StreamKind::TextContent, Type), Text(Text) {}
  191.  
  192.   static bool classof(const Stream *S) {
  193.     return S->Kind == StreamKind::TextContent;
  194.   }
  195. };
  196.  
  197. /// The top level structure representing a minidump object, consisting of a
  198. /// minidump header, and zero or more streams. To construct an Object from a
  199. /// minidump file, use the static create function. To serialize to/from yaml,
  200. /// use the appropriate streaming operator on a yaml stream.
  201. struct Object {
  202.   Object() = default;
  203.   Object(const Object &) = delete;
  204.   Object &operator=(const Object &) = delete;
  205.   Object(Object &&) = default;
  206.   Object &operator=(Object &&) = default;
  207.  
  208.   Object(const minidump::Header &Header,
  209.          std::vector<std::unique_ptr<Stream>> Streams)
  210.       : Header(Header), Streams(std::move(Streams)) {}
  211.  
  212.   /// The minidump header.
  213.   minidump::Header Header;
  214.  
  215.   /// The list of streams in this minidump object.
  216.   std::vector<std::unique_ptr<Stream>> Streams;
  217.  
  218.   static Expected<Object> create(const object::MinidumpFile &File);
  219. };
  220.  
  221. } // namespace MinidumpYAML
  222.  
  223. namespace yaml {
  224. template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> {
  225.   static void output(const MinidumpYAML::BlockStringRef &Text, void *,
  226.                      raw_ostream &OS) {
  227.     OS << Text;
  228.   }
  229.  
  230.   static StringRef input(StringRef Scalar, void *,
  231.                          MinidumpYAML::BlockStringRef &Text) {
  232.     Text = Scalar;
  233.     return "";
  234.   }
  235. };
  236.  
  237. template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> {
  238.   static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
  239.   static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
  240. };
  241.  
  242. template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> {
  243.   static void mapping(IO &IO, minidump::MemoryDescriptor &Memory,
  244.                       BinaryRef &Content);
  245. };
  246.  
  247. } // namespace yaml
  248.  
  249. } // namespace llvm
  250.  
  251. LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryProtection)
  252. LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryState)
  253. LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryType)
  254.  
  255. LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture)
  256. LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform)
  257. LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType)
  258.  
  259. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo)
  260. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo)
  261. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info)
  262. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::Exception)
  263. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryInfo)
  264. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo)
  265.  
  266. LLVM_YAML_DECLARE_MAPPING_TRAITS(
  267.     llvm::MinidumpYAML::MemoryListStream::entry_type)
  268. LLVM_YAML_DECLARE_MAPPING_TRAITS(
  269.     llvm::MinidumpYAML::ModuleListStream::entry_type)
  270. LLVM_YAML_DECLARE_MAPPING_TRAITS(
  271.     llvm::MinidumpYAML::ThreadListStream::entry_type)
  272.  
  273. LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MinidumpYAML::Stream>)
  274. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type)
  275. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type)
  276. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type)
  277. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryInfo)
  278.  
  279. LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
  280.  
  281. #endif // LLVM_OBJECTYAML_MINIDUMPYAML_H
  282.