Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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