LLVM  17.0.0git
Minidump.h
Go to the documentation of this file.
1 //===- Minidump.h - Minidump object file 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_OBJECT_MINIDUMP_H
10 #define LLVM_OBJECT_MINIDUMP_H
11 
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/StringExtras.h"
14 #include "llvm/ADT/iterator.h"
16 #include "llvm/Object/Binary.h"
17 #include "llvm/Support/Error.h"
18 
19 namespace llvm {
20 namespace object {
21 
22 /// A class providing access to the contents of a minidump file.
23 class MinidumpFile : public Binary {
24 public:
25  /// Construct a new MinidumpFile object from the given memory buffer. Returns
26  /// an error if this file cannot be identified as a minidump file, or if its
27  /// contents are badly corrupted (i.e. we cannot read the stream directory).
29 
30  static bool classof(const Binary *B) { return B->isMinidump(); }
31 
32  /// Returns the contents of the minidump header.
33  const minidump::Header &header() const { return Header; }
34 
35  /// Returns the list of streams (stream directory entries) in this file.
36  ArrayRef<minidump::Directory> streams() const { return Streams; }
37 
38  /// Returns the raw contents of the stream given by the directory entry.
40  return getData().slice(Stream.Location.RVA, Stream.Location.DataSize);
41  }
42 
43  /// Returns the raw contents of the stream of the given type, or std::nullopt
44  /// if the file does not contain a stream of this type.
45  std::optional<ArrayRef<uint8_t>>
47 
48  /// Returns the raw contents of an object given by the LocationDescriptor. An
49  /// error is returned if the descriptor points outside of the minidump file.
52  return getDataSlice(getData(), Desc.RVA, Desc.DataSize);
53  }
54 
55  /// Returns the minidump string at the given offset. An error is returned if
56  /// we fail to parse the string, or the string is invalid UTF16.
57  Expected<std::string> getString(size_t Offset) const;
58 
59  /// Returns the contents of the SystemInfo stream, cast to the appropriate
60  /// type. An error is returned if the file does not contain this stream, or
61  /// the stream is smaller than the size of the SystemInfo structure. The
62  /// internal consistency of the stream is not checked in any way.
64  return getStream<minidump::SystemInfo>(minidump::StreamType::SystemInfo);
65  }
66 
67  /// Returns the module list embedded in the ModuleList stream. An error is
68  /// returned if the file does not contain this stream, or if the stream is
69  /// not large enough to contain the number of modules declared in the stream
70  /// header. The consistency of the Module entries themselves is not checked in
71  /// any way.
73  return getListStream<minidump::Module>(minidump::StreamType::ModuleList);
74  }
75 
76  /// Returns the thread list embedded in the ThreadList stream. An error is
77  /// returned if the file does not contain this stream, or if the stream is
78  /// not large enough to contain the number of threads declared in the stream
79  /// header. The consistency of the Thread entries themselves is not checked in
80  /// any way.
82  return getListStream<minidump::Thread>(minidump::StreamType::ThreadList);
83  }
84 
85  /// Returns the contents of the Exception stream. An error is returned if the
86  /// file does not contain this stream, or the stream is smaller than the size
87  /// of the ExceptionStream structure. The internal consistency of the stream
88  /// is not checked in any way.
90  return getStream<minidump::ExceptionStream>(
91  minidump::StreamType::Exception);
92  }
93 
94  /// Returns the list of descriptors embedded in the MemoryList stream. The
95  /// descriptors provide the content of interesting regions of memory at the
96  /// time the minidump was taken. An error is returned if the file does not
97  /// contain this stream, or if the stream is not large enough to contain the
98  /// number of memory descriptors declared in the stream header. The
99  /// consistency of the MemoryDescriptor entries themselves is not checked in
100  /// any way.
102  return getListStream<minidump::MemoryDescriptor>(
103  minidump::StreamType::MemoryList);
104  }
105 
107  : public iterator_facade_base<MemoryInfoIterator,
108  std::forward_iterator_tag,
109  minidump::MemoryInfo> {
110  public:
111  MemoryInfoIterator(ArrayRef<uint8_t> Storage, size_t Stride)
112  : Storage(Storage), Stride(Stride) {
113  assert(Storage.size() % Stride == 0);
114  }
115 
116  bool operator==(const MemoryInfoIterator &R) const {
117  return Storage.size() == R.Storage.size();
118  }
119 
121  assert(Storage.size() >= sizeof(minidump::MemoryInfo));
122  return *reinterpret_cast<const minidump::MemoryInfo *>(Storage.data());
123  }
124 
126  Storage = Storage.drop_front(Stride);
127  return *this;
128  }
129 
130  private:
131  ArrayRef<uint8_t> Storage;
132  size_t Stride;
133  };
134 
135  /// Returns the list of descriptors embedded in the MemoryInfoList stream. The
136  /// descriptors provide properties (e.g. permissions) of interesting regions
137  /// of memory at the time the minidump was taken. An error is returned if the
138  /// file does not contain this stream, or if the stream is not large enough to
139  /// contain the number of memory descriptors declared in the stream header.
140  /// The consistency of the MemoryInfoList entries themselves is not checked
141  /// in any way.
143 
144 private:
145  static Error createError(StringRef Str) {
146  return make_error<GenericBinaryError>(Str, object_error::parse_failed);
147  }
148 
149  static Error createEOFError() {
150  return make_error<GenericBinaryError>("Unexpected EOF",
152  }
153 
154  /// Return a slice of the given data array, with bounds checking.
155  static Expected<ArrayRef<uint8_t>> getDataSlice(ArrayRef<uint8_t> Data,
156  size_t Offset, size_t Size);
157 
158  /// Return the slice of the given data array as an array of objects of the
159  /// given type. The function checks that the input array is large enough to
160  /// contain the correct number of objects of the given type.
161  template <typename T>
162  static Expected<ArrayRef<T>> getDataSliceAs(ArrayRef<uint8_t> Data,
163  size_t Offset, size_t Count);
164 
165  MinidumpFile(MemoryBufferRef Source, const minidump::Header &Header,
166  ArrayRef<minidump::Directory> Streams,
167  DenseMap<minidump::StreamType, std::size_t> StreamMap)
168  : Binary(ID_Minidump, Source), Header(Header), Streams(Streams),
169  StreamMap(std::move(StreamMap)) {}
170 
171  ArrayRef<uint8_t> getData() const {
172  return arrayRefFromStringRef(Data.getBuffer());
173  }
174 
175  /// Return the stream of the given type, cast to the appropriate type. Checks
176  /// that the stream is large enough to hold an object of this type.
177  template <typename T>
178  Expected<const T &> getStream(minidump::StreamType Stream) const;
179 
180  /// Return the contents of a stream which contains a list of fixed-size items,
181  /// prefixed by the list size.
182  template <typename T>
183  Expected<ArrayRef<T>> getListStream(minidump::StreamType Stream) const;
184 
185  const minidump::Header &Header;
186  ArrayRef<minidump::Directory> Streams;
187  DenseMap<minidump::StreamType, std::size_t> StreamMap;
188 };
189 
190 template <typename T>
191 Expected<const T &> MinidumpFile::getStream(minidump::StreamType Type) const {
192  if (std::optional<ArrayRef<uint8_t>> Stream = getRawStream(Type)) {
193  if (Stream->size() >= sizeof(T))
194  return *reinterpret_cast<const T *>(Stream->data());
195  return createEOFError();
196  }
197  return createError("No such stream");
198 }
199 
200 template <typename T>
201 Expected<ArrayRef<T>> MinidumpFile::getDataSliceAs(ArrayRef<uint8_t> Data,
202  size_t Offset,
203  size_t Count) {
204  // Check for overflow.
205  if (Count > std::numeric_limits<size_t>::max() / sizeof(T))
206  return createEOFError();
207  Expected<ArrayRef<uint8_t>> Slice =
208  getDataSlice(Data, Offset, sizeof(T) * Count);
209  if (!Slice)
210  return Slice.takeError();
211  return ArrayRef<T>(reinterpret_cast<const T *>(Slice->data()), Count);
212 }
213 
214 } // end namespace object
215 } // end namespace llvm
216 
217 #endif // LLVM_OBJECT_MINIDUMP_H
llvm::object::object_error::unexpected_eof
@ unexpected_eof
llvm::object::MinidumpFile::getThreadList
Expected< ArrayRef< minidump::Thread > > getThreadList() const
Returns the thread list embedded in the ThreadList stream.
Definition: Minidump.h:81
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Minidump.h
llvm::object::MinidumpFile::MemoryInfoIterator::operator++
MemoryInfoIterator & operator++()
Definition: Minidump.h:125
Error.h
llvm::minidump::MemoryInfo
Definition: Minidump.h:104
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::minidump::LocationDescriptor
Specifies the location (and size) of various objects in the minidump file.
Definition: Minidump.h:59
llvm::minidump::LocationDescriptor::DataSize
support::ulittle32_t DataSize
Definition: Minidump.h:60
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::object::MinidumpFile::getString
Expected< std::string > getString(size_t Offset) const
Returns the minidump string at the given offset.
Definition: Minidump.cpp:25
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:160
llvm::minidump::Header
The minidump header is the first part of a minidump file.
Definition: Minidump.h:32
llvm::object::MinidumpFile::getExceptionStream
Expected< const minidump::ExceptionStream & > getExceptionStream() const
Returns the contents of the Exception stream.
Definition: Minidump.h:89
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::object::object_error::parse_failed
@ parse_failed
llvm::minidump::Directory::Location
LocationDescriptor Location
Definition: Minidump.h:122
llvm::object::MinidumpFile::create
static Expected< std::unique_ptr< MinidumpFile > > create(MemoryBufferRef Source)
Construct a new MinidumpFile object from the given memory buffer.
Definition: Minidump.cpp:112
llvm::object::MinidumpFile::MemoryInfoIterator::MemoryInfoIterator
MemoryInfoIterator(ArrayRef< uint8_t > Storage, size_t Stride)
Definition: Minidump.h:111
llvm::ArrayRef::slice
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:193
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::ArrayRef::drop_front
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:202
llvm::minidump::StreamType
StreamType
The type of a minidump stream identifies its contents.
Definition: Minidump.h:50
llvm::object::Binary::ID_Minidump
@ ID_Minidump
Definition: Binary.h:49
iterator.h
StringExtras.h
llvm::iterator_facade_base
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:80
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1862
llvm::object::MinidumpFile::getRawData
Expected< ArrayRef< uint8_t > > getRawData(minidump::LocationDescriptor Desc) const
Returns the raw contents of an object given by the LocationDescriptor.
Definition: Minidump.h:51
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition: MemoryBufferRef.h:32
llvm::object::MinidumpFile::classof
static bool classof(const Binary *B)
Definition: Minidump.h:30
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:100
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:33
llvm::object::MinidumpFile::MemoryInfoIterator::operator*
const minidump::MemoryInfo & operator*() const
Definition: Minidump.h:120
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::object::Binary
Definition: Binary.h:32
llvm::object::MinidumpFile::streams
ArrayRef< minidump::Directory > streams() const
Returns the list of streams (stream directory entries) in this file.
Definition: Minidump.h:36
llvm::object::MinidumpFile::getSystemInfo
Expected< const minidump::SystemInfo & > getSystemInfo() const
Returns the contents of the SystemInfo stream, cast to the appropriate type.
Definition: Minidump.h:63
std
Definition: BitVector.h:851
llvm::minidump::Directory
Specifies the location and type of a single stream in the minidump file.
Definition: Minidump.h:120
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
llvm::object::MinidumpFile::getRawStream
ArrayRef< uint8_t > getRawStream(const minidump::Directory &Stream) const
Returns the raw contents of the stream given by the directory entry.
Definition: Minidump.h:39
llvm::object::MinidumpFile::getModuleList
Expected< ArrayRef< minidump::Module > > getModuleList() const
Returns the module list embedded in the ModuleList stream.
Definition: Minidump.h:72
llvm::object::MinidumpFile::header
const minidump::Header & header() const
Returns the contents of the minidump header.
Definition: Minidump.h:33
Binary.h
llvm::object::MinidumpFile
A class providing access to the contents of a minidump file.
Definition: Minidump.h:23
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::object::MinidumpFile::MemoryInfoIterator
Definition: Minidump.h:106
llvm::minidump::LocationDescriptor::RVA
support::ulittle32_t RVA
Definition: Minidump.h:61
llvm::object::MinidumpFile::MemoryInfoIterator::operator==
bool operator==(const MemoryInfoIterator &R) const
Definition: Minidump.h:116
llvm::object::Binary::Binary
Binary()=delete
llvm::object::MinidumpFile::getMemoryInfoList
Expected< iterator_range< MemoryInfoIterator > > getMemoryInfoList() const
Returns the list of descriptors embedded in the MemoryInfoList stream.
Definition: Minidump.cpp:57
llvm::object::MinidumpFile::getMemoryList
Expected< ArrayRef< minidump::MemoryDescriptor > > getMemoryList() const
Returns the list of descriptors embedded in the MemoryList stream.
Definition: Minidump.h:101