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
{
37 Stream(StreamKind Kind
, minidump::StreamType Type
) : Kind(Kind
), Type(Type
) {}
38 virtual ~Stream(); // anchor
40 const StreamKind Kind
;
41 const minidump::StreamType Type
;
43 /// Get the stream Kind used for representing streams of a given Type.
44 static StreamKind
getKind(minidump::StreamType Type
);
46 /// Create an empty stream of the given Type.
47 static std::unique_ptr
<Stream
> create(minidump::StreamType Type
);
49 /// Create a stream from the given stream directory entry.
50 static Expected
<std::unique_ptr
<Stream
>>
51 create(const minidump::Directory
&StreamDesc
,
52 const object::MinidumpFile
&File
);
56 /// A stream representing a list of abstract entries in a minidump stream. Its
57 /// instantiations can be used to represent the ModuleList stream and other
58 /// streams with a similar structure.
59 template <typename EntryT
> struct ListStream
: public Stream
{
60 using entry_type
= EntryT
;
62 std::vector
<entry_type
> Entries
;
64 explicit ListStream(std::vector
<entry_type
> Entries
= {})
65 : Stream(EntryT::Kind
, EntryT::Type
), Entries(std::move(Entries
)) {}
67 static bool classof(const Stream
*S
) { return S
->Kind
== EntryT::Kind
; }
70 /// A structure containing all data belonging to a single minidump module.
72 static constexpr Stream::StreamKind Kind
= Stream::StreamKind::ModuleList
;
73 static constexpr minidump::StreamType Type
= minidump::StreamType::ModuleList
;
75 minidump::Module Entry
;
77 yaml::BinaryRef CvRecord
;
78 yaml::BinaryRef MiscRecord
;
81 /// A structure containing all data belonging to a single minidump thread.
83 static constexpr Stream::StreamKind Kind
= Stream::StreamKind::ThreadList
;
84 static constexpr minidump::StreamType Type
= minidump::StreamType::ThreadList
;
86 minidump::Thread Entry
;
87 yaml::BinaryRef Stack
;
88 yaml::BinaryRef Context
;
91 /// A structure containing all data describing a single memory region.
92 struct ParsedMemoryDescriptor
{
93 static constexpr Stream::StreamKind Kind
= Stream::StreamKind::MemoryList
;
94 static constexpr minidump::StreamType Type
= minidump::StreamType::MemoryList
;
96 minidump::MemoryDescriptor Entry
;
97 yaml::BinaryRef Content
;
101 using ModuleListStream
= detail::ListStream
<detail::ParsedModule
>;
102 using ThreadListStream
= detail::ListStream
<detail::ParsedThread
>;
103 using MemoryListStream
= detail::ListStream
<detail::ParsedMemoryDescriptor
>;
105 /// A minidump stream represented as a sequence of hex bytes. This is used as a
106 /// fallback when no other stream kind is suitable.
107 struct RawContentStream
: public Stream
{
108 yaml::BinaryRef Content
;
111 RawContentStream(minidump::StreamType Type
, ArrayRef
<uint8_t> Content
= {})
112 : Stream(StreamKind::RawContent
, Type
), Content(Content
),
113 Size(Content
.size()) {}
115 static bool classof(const Stream
*S
) {
116 return S
->Kind
== StreamKind::RawContent
;
120 /// SystemInfo minidump stream.
121 struct SystemInfoStream
: public Stream
{
122 minidump::SystemInfo Info
;
123 std::string CSDVersion
;
125 explicit SystemInfoStream(const minidump::SystemInfo
&Info
,
126 std::string CSDVersion
)
127 : Stream(StreamKind::SystemInfo
, minidump::StreamType::SystemInfo
),
128 Info(Info
), CSDVersion(std::move(CSDVersion
)) {}
131 : Stream(StreamKind::SystemInfo
, minidump::StreamType::SystemInfo
) {
132 memset(&Info
, 0, sizeof(Info
));
135 static bool classof(const Stream
*S
) {
136 return S
->Kind
== StreamKind::SystemInfo
;
140 /// A StringRef, which is printed using YAML block notation.
141 LLVM_YAML_STRONG_TYPEDEF(StringRef
, BlockStringRef
)
143 /// A minidump stream containing textual data (typically, the contents of a
144 /// /proc/<pid> file on linux).
145 struct TextContentStream
: public Stream
{
148 TextContentStream(minidump::StreamType Type
, StringRef Text
= {})
149 : Stream(StreamKind::TextContent
, Type
), Text(Text
) {}
151 static bool classof(const Stream
*S
) {
152 return S
->Kind
== StreamKind::TextContent
;
156 /// The top level structure representing a minidump object, consisting of a
157 /// minidump header, and zero or more streams. To construct an Object from a
158 /// minidump file, use the static create function. To serialize to/from yaml,
159 /// use the appropriate streaming operator on a yaml stream.
162 Object(const Object
&) = delete;
163 Object
&operator=(const Object
&) = delete;
164 Object(Object
&&) = default;
165 Object
&operator=(Object
&&) = default;
167 Object(const minidump::Header
&Header
,
168 std::vector
<std::unique_ptr
<Stream
>> Streams
)
169 : Header(Header
), Streams(std::move(Streams
)) {}
171 /// The minidump header.
172 minidump::Header Header
;
174 /// The list of streams in this minidump object.
175 std::vector
<std::unique_ptr
<Stream
>> Streams
;
177 static Expected
<Object
> create(const object::MinidumpFile
&File
);
180 } // namespace MinidumpYAML
183 template <> struct BlockScalarTraits
<MinidumpYAML::BlockStringRef
> {
184 static void output(const MinidumpYAML::BlockStringRef
&Text
, void *,
189 static StringRef
input(StringRef Scalar
, void *,
190 MinidumpYAML::BlockStringRef
&Text
) {
196 template <> struct MappingTraits
<std::unique_ptr
<MinidumpYAML::Stream
>> {
197 static void mapping(IO
&IO
, std::unique_ptr
<MinidumpYAML::Stream
> &S
);
198 static StringRef
validate(IO
&IO
, std::unique_ptr
<MinidumpYAML::Stream
> &S
);
201 template <> struct MappingContextTraits
<minidump::MemoryDescriptor
, BinaryRef
> {
202 static void mapping(IO
&IO
, minidump::MemoryDescriptor
&Memory
,
210 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture
)
211 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform
)
212 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType
)
214 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo
)
215 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo
)
216 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info
)
217 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo
)
219 LLVM_YAML_DECLARE_MAPPING_TRAITS(
220 llvm::MinidumpYAML::MemoryListStream::entry_type
)
221 LLVM_YAML_DECLARE_MAPPING_TRAITS(
222 llvm::MinidumpYAML::ModuleListStream::entry_type
)
223 LLVM_YAML_DECLARE_MAPPING_TRAITS(
224 llvm::MinidumpYAML::ThreadListStream::entry_type
)
226 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr
<llvm::MinidumpYAML::Stream
>)
227 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type
)
228 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type
)
229 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type
)
231 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object
)
233 #endif // LLVM_OBJECTYAML_MINIDUMPYAML_H