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()),

55 sizeof(T) * Data.size()});

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.