Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:21

0001 //===- MinidumpYAML.h - Minidump YAMLIO implementation ----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_OBJECTYAML_MINIDUMPYAML_H
0010 #define LLVM_OBJECTYAML_MINIDUMPYAML_H
0011 
0012 #include "llvm/BinaryFormat/Minidump.h"
0013 #include "llvm/Object/Minidump.h"
0014 #include "llvm/ObjectYAML/YAML.h"
0015 #include "llvm/Support/YAMLTraits.h"
0016 
0017 namespace llvm {
0018 namespace MinidumpYAML {
0019 
0020 /// The base class for all minidump streams. The "Type" of the stream
0021 /// corresponds to the Stream Type field in the minidump file. The "Kind" field
0022 /// specifies how are we going to treat it. For highly specialized streams (e.g.
0023 /// SystemInfo), there is a 1:1 mapping between Types and Kinds, but in general
0024 /// one stream Kind can be used to represent multiple stream Types (e.g. any
0025 /// unrecognised stream Type will be handled via RawContentStream). The mapping
0026 /// from Types to Kinds is fixed and given by the static getKind function.
0027 struct Stream {
0028   enum class StreamKind {
0029     Exception,
0030     MemoryInfoList,
0031     MemoryList,
0032     Memory64List,
0033     ModuleList,
0034     RawContent,
0035     SystemInfo,
0036     TextContent,
0037     ThreadList,
0038   };
0039 
0040   Stream(StreamKind Kind, minidump::StreamType Type) : Kind(Kind), Type(Type) {}
0041   virtual ~Stream(); // anchor
0042 
0043   const StreamKind Kind;
0044   const minidump::StreamType Type;
0045 
0046   /// Get the stream Kind used for representing streams of a given Type.
0047   static StreamKind getKind(minidump::StreamType Type);
0048 
0049   /// Create an empty stream of the given Type.
0050   static std::unique_ptr<Stream> create(minidump::StreamType Type);
0051 
0052   /// Create a stream from the given stream directory entry.
0053   static Expected<std::unique_ptr<Stream>>
0054   create(const minidump::Directory &StreamDesc,
0055          const object::MinidumpFile &File);
0056 };
0057 
0058 namespace detail {
0059 /// A stream representing a list of abstract entries in a minidump stream. Its
0060 /// instantiations can be used to represent the ModuleList stream and other
0061 /// streams with a similar structure.
0062 template <typename EntryT> struct ListStream : public Stream {
0063   using entry_type = EntryT;
0064 
0065   std::vector<entry_type> Entries;
0066 
0067   explicit ListStream(std::vector<entry_type> Entries = {})
0068       : Stream(EntryT::Kind, EntryT::Type), Entries(std::move(Entries)) {}
0069 
0070   static bool classof(const Stream *S) { return S->Kind == EntryT::Kind; }
0071 };
0072 
0073 /// A structure containing all data belonging to a single minidump module.
0074 struct ParsedModule {
0075   static constexpr Stream::StreamKind Kind = Stream::StreamKind::ModuleList;
0076   static constexpr minidump::StreamType Type = minidump::StreamType::ModuleList;
0077 
0078   minidump::Module Entry;
0079   std::string Name;
0080   yaml::BinaryRef CvRecord;
0081   yaml::BinaryRef MiscRecord;
0082 };
0083 
0084 /// A structure containing all data belonging to a single minidump thread.
0085 struct ParsedThread {
0086   static constexpr Stream::StreamKind Kind = Stream::StreamKind::ThreadList;
0087   static constexpr minidump::StreamType Type = minidump::StreamType::ThreadList;
0088 
0089   minidump::Thread Entry;
0090   yaml::BinaryRef Stack;
0091   yaml::BinaryRef Context;
0092 };
0093 
0094 /// A structure containing all data describing a single memory region.
0095 struct ParsedMemoryDescriptor {
0096   static constexpr Stream::StreamKind Kind = Stream::StreamKind::MemoryList;
0097   static constexpr minidump::StreamType Type = minidump::StreamType::MemoryList;
0098 
0099   minidump::MemoryDescriptor Entry;
0100   yaml::BinaryRef Content;
0101 };
0102 
0103 struct ParsedMemory64Descriptor {
0104   static constexpr Stream::StreamKind Kind = Stream::StreamKind::Memory64List;
0105   static constexpr minidump::StreamType Type =
0106       minidump::StreamType::Memory64List;
0107 
0108   minidump::MemoryDescriptor_64 Entry;
0109   yaml::BinaryRef Content;
0110 };
0111 } // namespace detail
0112 
0113 using ModuleListStream = detail::ListStream<detail::ParsedModule>;
0114 using ThreadListStream = detail::ListStream<detail::ParsedThread>;
0115 using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
0116 
0117 struct Memory64ListStream
0118     : public detail::ListStream<detail::ParsedMemory64Descriptor> {
0119   minidump::Memory64ListHeader Header;
0120 
0121   explicit Memory64ListStream(
0122       std::vector<detail::ParsedMemory64Descriptor> Entries = {})
0123       : ListStream(Entries) {}
0124 };
0125 
0126 /// ExceptionStream minidump stream.
0127 struct ExceptionStream : public Stream {
0128   minidump::ExceptionStream MDExceptionStream;
0129   yaml::BinaryRef ThreadContext;
0130 
0131   ExceptionStream()
0132       : Stream(StreamKind::Exception, minidump::StreamType::Exception),
0133         MDExceptionStream({}) {}
0134 
0135   explicit ExceptionStream(const minidump::ExceptionStream &MDExceptionStream,
0136                            ArrayRef<uint8_t> ThreadContext)
0137       : Stream(StreamKind::Exception, minidump::StreamType::Exception),
0138         MDExceptionStream(MDExceptionStream), ThreadContext(ThreadContext) {}
0139 
0140   static bool classof(const Stream *S) {
0141     return S->Kind == StreamKind::Exception;
0142   }
0143 };
0144 
0145 /// A structure containing the list of MemoryInfo entries comprising a
0146 /// MemoryInfoList stream.
0147 struct MemoryInfoListStream : public Stream {
0148   std::vector<minidump::MemoryInfo> Infos;
0149 
0150   MemoryInfoListStream()
0151       : Stream(StreamKind::MemoryInfoList,
0152                minidump::StreamType::MemoryInfoList) {}
0153 
0154   explicit MemoryInfoListStream(
0155       iterator_range<object::MinidumpFile::MemoryInfoIterator> Range)
0156       : Stream(StreamKind::MemoryInfoList,
0157                minidump::StreamType::MemoryInfoList),
0158         Infos(Range.begin(), Range.end()) {}
0159 
0160   static bool classof(const Stream *S) {
0161     return S->Kind == StreamKind::MemoryInfoList;
0162   }
0163 };
0164 
0165 /// A minidump stream represented as a sequence of hex bytes. This is used as a
0166 /// fallback when no other stream kind is suitable.
0167 struct RawContentStream : public Stream {
0168   yaml::BinaryRef Content;
0169   yaml::Hex32 Size;
0170 
0171   RawContentStream(minidump::StreamType Type, ArrayRef<uint8_t> Content = {})
0172       : Stream(StreamKind::RawContent, Type), Content(Content),
0173         Size(Content.size()) {}
0174 
0175   static bool classof(const Stream *S) {
0176     return S->Kind == StreamKind::RawContent;
0177   }
0178 };
0179 
0180 /// SystemInfo minidump stream.
0181 struct SystemInfoStream : public Stream {
0182   minidump::SystemInfo Info;
0183   std::string CSDVersion;
0184 
0185   SystemInfoStream()
0186       : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo) {
0187     memset(&Info, 0, sizeof(Info));
0188   }
0189 
0190   explicit SystemInfoStream(const minidump::SystemInfo &Info,
0191                             std::string CSDVersion)
0192       : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
0193         Info(Info), CSDVersion(std::move(CSDVersion)) {}
0194 
0195   static bool classof(const Stream *S) {
0196     return S->Kind == StreamKind::SystemInfo;
0197   }
0198 };
0199 
0200 /// A StringRef, which is printed using YAML block notation.
0201 LLVM_YAML_STRONG_TYPEDEF(StringRef, BlockStringRef)
0202 
0203 /// A minidump stream containing textual data (typically, the contents of a
0204 /// /proc/<pid> file on linux).
0205 struct TextContentStream : public Stream {
0206   BlockStringRef Text;
0207 
0208   TextContentStream(minidump::StreamType Type, StringRef Text = {})
0209       : Stream(StreamKind::TextContent, Type), Text(Text) {}
0210 
0211   static bool classof(const Stream *S) {
0212     return S->Kind == StreamKind::TextContent;
0213   }
0214 };
0215 
0216 /// The top level structure representing a minidump object, consisting of a
0217 /// minidump header, and zero or more streams. To construct an Object from a
0218 /// minidump file, use the static create function. To serialize to/from yaml,
0219 /// use the appropriate streaming operator on a yaml stream.
0220 struct Object {
0221   Object() = default;
0222   Object(const Object &) = delete;
0223   Object &operator=(const Object &) = delete;
0224   Object(Object &&) = default;
0225   Object &operator=(Object &&) = default;
0226 
0227   Object(const minidump::Header &Header,
0228          std::vector<std::unique_ptr<Stream>> Streams)
0229       : Header(Header), Streams(std::move(Streams)) {}
0230 
0231   /// The minidump header.
0232   minidump::Header Header;
0233 
0234   /// The list of streams in this minidump object.
0235   std::vector<std::unique_ptr<Stream>> Streams;
0236 
0237   static Expected<Object> create(const object::MinidumpFile &File);
0238 };
0239 
0240 } // namespace MinidumpYAML
0241 
0242 namespace yaml {
0243 template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> {
0244   static void output(const MinidumpYAML::BlockStringRef &Text, void *,
0245                      raw_ostream &OS) {
0246     OS << Text;
0247   }
0248 
0249   static StringRef input(StringRef Scalar, void *,
0250                          MinidumpYAML::BlockStringRef &Text) {
0251     Text = Scalar;
0252     return "";
0253   }
0254 };
0255 
0256 template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> {
0257   static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
0258   static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
0259 };
0260 
0261 template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> {
0262   static void mapping(IO &IO, minidump::MemoryDescriptor &Memory,
0263                       BinaryRef &Content);
0264 };
0265 
0266 template <>
0267 struct MappingContextTraits<minidump::MemoryDescriptor_64, BinaryRef> {
0268   static void mapping(IO &IO, minidump::MemoryDescriptor_64 &Memory,
0269                       BinaryRef &Content);
0270 };
0271 
0272 } // namespace yaml
0273 
0274 } // namespace llvm
0275 
0276 LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryProtection)
0277 LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryState)
0278 LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryType)
0279 
0280 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture)
0281 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform)
0282 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType)
0283 
0284 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo)
0285 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo)
0286 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info)
0287 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::Exception)
0288 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryInfo)
0289 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo)
0290 
0291 LLVM_YAML_DECLARE_MAPPING_TRAITS(
0292     llvm::MinidumpYAML::MemoryListStream::entry_type)
0293 LLVM_YAML_DECLARE_MAPPING_TRAITS(
0294     llvm::MinidumpYAML::ModuleListStream::entry_type)
0295 LLVM_YAML_DECLARE_MAPPING_TRAITS(
0296     llvm::MinidumpYAML::ThreadListStream::entry_type)
0297 LLVM_YAML_DECLARE_MAPPING_TRAITS(
0298     llvm::MinidumpYAML::Memory64ListStream::entry_type)
0299 
0300 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MinidumpYAML::Stream>)
0301 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type)
0302 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type)
0303 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type)
0304 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::Memory64ListStream::entry_type)
0305 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryInfo)
0306 
0307 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
0308 
0309 #endif // LLVM_OBJECTYAML_MINIDUMPYAML_H