LLVM: lib/ObjectYAML/MinidumpEmitter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
13#include
14
15using namespace llvm;
18
19namespace {
20
21
22
23
24
25
26
27
28
29
30class BlobAllocator {
31public:
32 size_t tell() const { return NextOffset; }
33
34 size_t allocateCallback(size_t Size,
35 std::function<void(raw_ostream &)> Callback) {
36 size_t Offset = NextOffset;
37 NextOffset += Size;
38 Callbacks.push_back(std::move(Callback));
40 }
41
42 size_t allocateBytes(ArrayRef<uint8_t> Data) {
43 return allocateCallback(
44 Data.size(), [Data](raw_ostream &OS) { OS << toStringRef(Data); });
45 }
46
47 size_t allocateBytes(yaml::BinaryRef Data) {
48 return allocateCallback(Data.binary_size(), [Data](raw_ostream &OS) {
49 Data.writeAsBinary(OS);
50 });
51 }
52
53 template size_t allocateArray(ArrayRef Data) {
54 return allocateBytes({reinterpret_cast<const uint8_t *>(Data.data()),
56 }
57
58 template <typename T, typename RangeType>
59 std::pair<size_t, MutableArrayRef>
61
62 template size_t allocateObject(const T &Data) {
64 }
65
66 template <typename T, typename... Types>
67 std::pair<size_t, T *> allocateNewObject(Types &&... Args) {
68 T *Object = new (Temporaries.Allocate<T>()) T(std::forward(Args)...);
69 return {allocateObject(*Object), Object};
70 }
71
72 size_t allocateString(StringRef Str);
73
74 void writeTo(raw_ostream &OS) const;
75
76private:
77 size_t NextOffset = 0;
78
80 std::vector<std::function<void(raw_ostream &)>> Callbacks;
81};
82}
83
84template <typename T, typename RangeType>
85std::pair<size_t, MutableArrayRef>
90 return {allocateArray(Array), Array};
91}
92
93size_t BlobAllocator::allocateString(StringRef Str) {
96 assert(OK && "Invalid UTF8 in Str?");
97 (void)OK;
98
99
100
103 allocateNewObjectsupport::ulittle32\_t(2 * (WStr.size() - 1)).first;
104 allocateNewArraysupport::ulittle16\_t(make_range(WStr.begin(), WStr.end()));
106}
107
108void BlobAllocator::writeTo(raw_ostream &OS) const {
109 size_t BeginOffset = OS.tell();
110 for (const auto &Callback : Callbacks)
112 assert(OS.tell() == BeginOffset + NextOffset &&
113 "Callbacks wrote an unexpected number of bytes.");
114 (void)BeginOffset;
115}
116
121
124
125 size_t DataEnd = File.tell();
126
127
128
129
130
131
132
133
135
136 return DataEnd;
137}
138
144 File.allocateObject(S.Header);
146 File.allocateObject(E.Entry);
147
148
149 size_t DataEnd = File.tell();
151 File.allocateBytes(E.Content);
152 if (E.Entry.DataSize > E.Content.binary_size()) {
153 size_t Padding = E.Entry.DataSize - E.Content.binary_size();
154 File.allocateCallback(Padding, [Padding](raw_ostream &OS) {
155 OS << std::string(Padding, '\0');
156 });
157 }
158 }
159
160 return DataEnd;
161}
162
166
168 M.Entry.ModuleNameRVA = File.allocateString(M.Name);
169
170 M.Entry.CvRecord = layout(File, M.CvRecord);
171 M.Entry.MiscRecord = layout(File, M.MiscRecord);
172}
173
175 T.Entry.Stack.Memory = layout(File, T.Stack);
176 T.Entry.Context = layout(File, T.Context);
177}
178
179template
180static size_t layout(BlobAllocator &File,
182
185 File.allocateObject(E.Entry);
186
187 size_t DataEnd = File.tell();
188
189
190 DataEnd = File.tell();
193
194 return DataEnd;
195}
196
199 Result.Type = S.Type;
200 Result.Location.RVA = File.tell();
201 std::optional<size_t> DataEnd;
202 switch (S.Kind) {
205 break;
210 InfoList.Infos.size());
212 break;
213 }
216 break;
219 break;
222 break;
225 File.allocateCallback(Raw.Size, [&Raw](raw_ostream &OS) {
226 Raw.Content.writeAsBinary(OS);
227 assert(Raw.Content.binary_size() <= Raw.Size);
228 OS << std::string(Raw.Size - Raw.Content.binary_size(), '\0');
229 });
230 break;
231 }
234 File.allocateObject(SystemInfo.Info);
235
236 DataEnd = File.tell();
238 break;
239 }
242 break;
245 break;
246 }
247
248
249 Result.Location.DataSize =
250 DataEnd.value_or(File.tell()) - Result.Location.RVA;
251 return Result;
252}
253
254namespace llvm {
255namespace yaml {
256
259 BlobAllocator File;
260 File.allocateObject(Obj.Header);
261
262 std::vector StreamDirectory(Obj.Streams.size());
263 Obj.Header.StreamDirectoryRVA = File.allocateArray(ArrayRef(StreamDirectory));
264 Obj.Header.NumberOfStreams = StreamDirectory.size();
265
266 for (const auto &[Index, Stream] : enumerate(Obj.Streams))
267 StreamDirectory[Index] = layout(File, *Stream);
268
269 File.writeTo(Out);
270 return true;
271}
272
273}
274}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static LocationDescriptor layout(BlobAllocator &File, yaml::BinaryRef Data)
Definition MinidumpEmitter.cpp:117
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
void push_back(const T &Elt)
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t tell() const
tell - Return the current offset with the file.
Specialized YAMLIO scalar type for representing a binary blob.
This class represents a YAML stream potentially containing multiple documents.
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback is a void function that accepts Expected.
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
llvm::function_ref< void(const Twine &Msg)> ErrorHandler
LLVM_ABI bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH)
Definition MinidumpEmitter.cpp:257
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto uninitialized_copy(R &&Src, IterTy Dst)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
FunctionAddr VTableAddr uintptr_t uintptr_t Data
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI bool convertUTF8ToUTF16String(StringRef SrcUTF8, SmallVectorImpl< UTF16 > &DstUTF16)
Converts a UTF-8 string into a UTF-16 string with native endianness.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
ExceptionStream minidump stream.
minidump::ExceptionStream MDExceptionStream
yaml::BinaryRef ThreadContext
minidump::Memory64ListHeader Header
A structure containing the list of MemoryInfo entries comprising a MemoryInfoList stream.
std::vector< minidump::MemoryInfo > Infos
The top level structure representing a minidump object, consisting of a minidump header,...
A minidump stream represented as a sequence of hex bytes.
The base class for all minidump streams.
const minidump::StreamType Type
SystemInfo minidump stream.
A stream representing a list of abstract entries in a minidump stream.
detail::ParsedMemoryDescriptor entry_type
std::vector< entry_type > Entries
Specifies the location and type of a single stream in the minidump file.
LocationDescriptor ThreadContext
Specifies the location (and size) of various objects in the minidump file.
The SystemInfo stream, containing various information about the system where this minidump was genera...
support::ulittle32_t CSDVersionRVA
Common declarations for yaml2obj.