|
15 | 15 | #include "llvm/ADT/iterator.h" |
16 | 16 | #include "llvm/BinaryFormat/Minidump.h" |
17 | 17 | #include "llvm/Object/Binary.h" |
18 | | -#include "llvm/Support/Compiler.h" |
19 | 18 | #include "llvm/Support/Error.h" |
20 | 19 |
|
21 | 20 | namespace llvm { |
22 | | -namespace minidump { |
23 | | -struct Module; |
24 | | -struct Thread; |
25 | | -struct MemoryDescriptor; |
26 | | -} // namespace minidump |
27 | 21 | namespace object { |
28 | 22 |
|
29 | 23 | /// A class providing access to the contents of a minidump file. |
@@ -377,13 +371,27 @@ Expected<ArrayRef<T>> MinidumpFile::getDataSliceAs(ArrayRef<uint8_t> Data, |
377 | 371 | return ArrayRef<T>(reinterpret_cast<const T *>(Slice->data()), Count); |
378 | 372 | } |
379 | 373 |
|
380 | | -// Needed by MinidumpTest.cpp |
381 | | -extern template LLVM_TEMPLATE_ABI Expected<ArrayRef<minidump::Module>> |
382 | | - MinidumpFile::getListStream(minidump::StreamType) const; |
383 | | -extern template LLVM_TEMPLATE_ABI Expected<ArrayRef<minidump::Thread>> |
384 | | - MinidumpFile::getListStream(minidump::StreamType) const; |
385 | | -extern template LLVM_TEMPLATE_ABI Expected<ArrayRef<minidump::MemoryDescriptor>> |
386 | | - MinidumpFile::getListStream(minidump::StreamType) const; |
| 374 | +template <typename T> |
| 375 | +Expected<ArrayRef<T>> |
| 376 | +MinidumpFile::getListStream(minidump::StreamType Type) const { |
| 377 | + std::optional<ArrayRef<uint8_t>> Stream = getRawStream(Type); |
| 378 | + if (!Stream) |
| 379 | + return createError("No such stream"); |
| 380 | + auto ExpectedSize = getDataSliceAs<support::ulittle32_t>(*Stream, 0, 1); |
| 381 | + if (!ExpectedSize) |
| 382 | + return ExpectedSize.takeError(); |
| 383 | + |
| 384 | + size_t ListSize = ExpectedSize.get()[0]; |
| 385 | + |
| 386 | + size_t ListOffset = 4; |
| 387 | + // Some producers insert additional padding bytes to align the list to an |
| 388 | + // 8-byte boundary. Check for that by comparing the list size with the overall |
| 389 | + // stream size. |
| 390 | + if (ListOffset + sizeof(T) * ListSize < Stream->size()) |
| 391 | + ListOffset = 8; |
| 392 | + |
| 393 | + return getDataSliceAs<T>(*Stream, ListOffset, ListSize); |
| 394 | +} |
387 | 395 |
|
388 | 396 | } // end namespace object |
389 | 397 | } // end namespace llvm |
|
0 commit comments