1 //===- MinidumpYAML.h - Minidump YAMLIO implementation ----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_OBJECTYAML_MINIDUMPYAML_H
10 #define LLVM_OBJECTYAML_MINIDUMPYAML_H
12 #include "llvm/BinaryFormat/Minidump.h"
13 #include "llvm/Object/Minidump.h"
14 #include "llvm/ObjectYAML/YAML.h"
15 #include "llvm/Support/YAMLTraits.h"
18 namespace MinidumpYAML
{
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.
28 enum class StreamKind
{
39 Stream(StreamKind Kind
, minidump::StreamType Type
) : Kind(Kind
), Type(Type
) {}
40 virtual ~Stream(); // anchor
42 const StreamKind Kind
;
43 const minidump::StreamType Type
;
45 /// Get the stream Kind used for representing streams of a given Type.
46 static StreamKind
getKind(minidump::StreamType Type
);
48 /// Create an empty stream of the given Type.
49 static std::unique_ptr
<Stream
> create(minidump::StreamType Type
);
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
);
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
;
64 std::vector
<entry_type
> Entries
;
66 explicit ListStream(std::vector
<entry_type
> Entries
= {})
67 : Stream(EntryT::Kind
, EntryT::Type
), Entries(std::move(Entries
)) {}
69 static bool classof(const Stream
*S
) { return S
->Kind
== EntryT::Kind
; }
72 /// A structure containing all data belonging to a single minidump module.
74 static constexpr Stream::StreamKind Kind
= Stream::StreamKind::ModuleList
;
75 static constexpr minidump::StreamType Type
= minidump::StreamType::ModuleList
;
77 minidump::Module Entry
;
79 yaml::BinaryRef CvRecord
;
80 yaml::BinaryRef MiscRecord
;
83 /// A structure containing all data belonging to a single minidump thread.
85 static constexpr Stream::StreamKind Kind
= Stream::StreamKind::ThreadList
;
86 static constexpr minidump::StreamType Type
= minidump::StreamType::ThreadList
;
88 minidump::Thread Entry
;
89 yaml::BinaryRef Stack
;
90 yaml::BinaryRef Context
;
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
;
98 minidump::MemoryDescriptor Entry
;
99 yaml::BinaryRef Content
;
101 } // namespace detail
103 using ModuleListStream
= detail::ListStream
<detail::ParsedModule
>;
104 using ThreadListStream
= detail::ListStream
<detail::ParsedThread
>;
105 using MemoryListStream
= detail::ListStream
<detail::ParsedMemoryDescriptor
>;
107 /// ExceptionStream minidump stream.
108 struct ExceptionStream
: public Stream
{
109 minidump::ExceptionStream MDExceptionStream
;
110 yaml::BinaryRef ThreadContext
;
113 : Stream(StreamKind::Exception
, minidump::StreamType::Exception
),
114 MDExceptionStream({}) {}
116 explicit ExceptionStream(const minidump::ExceptionStream
&MDExceptionStream
,
117 ArrayRef
<uint8_t> ThreadContext
)
118 : Stream(StreamKind::Exception
, minidump::StreamType::Exception
),
119 MDExceptionStream(MDExceptionStream
), ThreadContext(ThreadContext
) {}
121 static bool classof(const Stream
*S
) {
122 return S
->Kind
== StreamKind::Exception
;
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
;
131 MemoryInfoListStream()
132 : Stream(StreamKind::MemoryInfoList
,
133 minidump::StreamType::MemoryInfoList
) {}
135 explicit MemoryInfoListStream(
136 iterator_range
<object::MinidumpFile::MemoryInfoIterator
> Range
)
137 : Stream(StreamKind::MemoryInfoList
,
138 minidump::StreamType::MemoryInfoList
),
139 Infos(Range
.begin(), Range
.end()) {}
141 static bool classof(const Stream
*S
) {
142 return S
->Kind
== StreamKind::MemoryInfoList
;
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
;
152 RawContentStream(minidump::StreamType Type
, ArrayRef
<uint8_t> Content
= {})
153 : Stream(StreamKind::RawContent
, Type
), Content(Content
),
154 Size(Content
.size()) {}
156 static bool classof(const Stream
*S
) {
157 return S
->Kind
== StreamKind::RawContent
;
161 /// SystemInfo minidump stream.
162 struct SystemInfoStream
: public Stream
{
163 minidump::SystemInfo Info
;
164 std::string CSDVersion
;
167 : Stream(StreamKind::SystemInfo
, minidump::StreamType::SystemInfo
) {
168 memset(&Info
, 0, sizeof(Info
));
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
)) {}
176 static bool classof(const Stream
*S
) {
177 return S
->Kind
== StreamKind::SystemInfo
;
181 /// A StringRef, which is printed using YAML block notation.
182 LLVM_YAML_STRONG_TYPEDEF(StringRef
, BlockStringRef
)
184 /// A minidump stream containing textual data (typically, the contents of a
185 /// /proc/<pid> file on linux).
186 struct TextContentStream
: public Stream
{
189 TextContentStream(minidump::StreamType Type
, StringRef Text
= {})
190 : Stream(StreamKind::TextContent
, Type
), Text(Text
) {}
192 static bool classof(const Stream
*S
) {
193 return S
->Kind
== StreamKind::TextContent
;
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.
203 Object(const Object
&) = delete;
204 Object
&operator=(const Object
&) = delete;
205 Object(Object
&&) = default;
206 Object
&operator=(Object
&&) = default;
208 Object(const minidump::Header
&Header
,
209 std::vector
<std::unique_ptr
<Stream
>> Streams
)
210 : Header(Header
), Streams(std::move(Streams
)) {}
212 /// The minidump header.
213 minidump::Header Header
;
215 /// The list of streams in this minidump object.
216 std::vector
<std::unique_ptr
<Stream
>> Streams
;
218 static Expected
<Object
> create(const object::MinidumpFile
&File
);
221 } // namespace MinidumpYAML
224 template <> struct BlockScalarTraits
<MinidumpYAML::BlockStringRef
> {
225 static void output(const MinidumpYAML::BlockStringRef
&Text
, void *,
230 static StringRef
input(StringRef Scalar
, void *,
231 MinidumpYAML::BlockStringRef
&Text
) {
237 template <> struct MappingTraits
<std::unique_ptr
<MinidumpYAML::Stream
>> {
238 static void mapping(IO
&IO
, std::unique_ptr
<MinidumpYAML::Stream
> &S
);
239 static StringRef
validate(IO
&IO
, std::unique_ptr
<MinidumpYAML::Stream
> &S
);
242 template <> struct MappingContextTraits
<minidump::MemoryDescriptor
, BinaryRef
> {
243 static void mapping(IO
&IO
, minidump::MemoryDescriptor
&Memory
,
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
)
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
)
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
)
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
)
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
)
279 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object
)
281 #endif // LLVM_OBJECTYAML_MINIDUMPYAML_H