summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process')
-rw-r--r--lldb/source/Plugins/Process/minidump/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.cpp120
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.h10
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp10
4 files changed, 23 insertions, 118 deletions
diff --git a/lldb/source/Plugins/Process/minidump/CMakeLists.txt b/lldb/source/Plugins/Process/minidump/CMakeLists.txt
index c90f4f0579f..afa3550dfe4 100644
--- a/lldb/source/Plugins/Process/minidump/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/minidump/CMakeLists.txt
@@ -16,5 +16,6 @@ add_lldb_library(lldbPluginProcessMinidump PLUGIN
lldbPluginProcessElfCore
LINK_COMPONENTS
BinaryFormat
+ Object
Support
)
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 64af45f657c..eab0c039f54 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -10,8 +10,8 @@
#include "NtStructures.h"
#include "RegisterContextMinidump_x86_32.h"
-#include "lldb/Utility/LLDBAssert.h"
#include "Plugins/Process/Utility/LinuxProcMaps.h"
+#include "lldb/Utility/LLDBAssert.h"
// C includes
// C++ includes
@@ -23,11 +23,6 @@
using namespace lldb_private;
using namespace minidump;
-static llvm::Error stringError(llvm::StringRef Err) {
- return llvm::make_error<llvm::StringError>(Err,
- llvm::inconvertibleErrorCode());
-}
-
const Header *ParseHeader(llvm::ArrayRef<uint8_t> &data) {
const Header *header = nullptr;
Status error = consumeObject(data, header);
@@ -45,117 +40,26 @@ const Header *ParseHeader(llvm::ArrayRef<uint8_t> &data) {
llvm::Expected<MinidumpParser>
MinidumpParser::Create(const lldb::DataBufferSP &data_sp) {
- if (data_sp->GetByteSize() < sizeof(Header))
- return stringError("Buffer too small.");
-
- llvm::ArrayRef<uint8_t> header_data(data_sp->GetBytes(),
- sizeof(Header));
- const Header *header = ParseHeader(header_data);
- if (!header)
- return stringError("invalid minidump: can't parse the header");
-
- // A minidump without at least one stream is clearly ill-formed
- if (header->NumberOfStreams == 0)
- return stringError("invalid minidump: no streams present");
-
- struct FileRange {
- uint32_t offset = 0;
- uint32_t size = 0;
-
- FileRange(uint32_t offset, uint32_t size) : offset(offset), size(size) {}
- uint32_t end() const { return offset + size; }
- };
-
- const uint32_t file_size = data_sp->GetByteSize();
-
- // Build a global minidump file map, checking for:
- // - overlapping streams/data structures
- // - truncation (streams pointing past the end of file)
- std::vector<FileRange> minidump_map;
-
- minidump_map.emplace_back(0, sizeof(Header));
-
- // Add the directory entries to the file map
- FileRange directory_range(header->StreamDirectoryRVA,
- header->NumberOfStreams * sizeof(Directory));
- if (directory_range.end() > file_size)
- return stringError("invalid minidump: truncated streams directory");
- minidump_map.push_back(directory_range);
-
- llvm::DenseMap<StreamType, LocationDescriptor> directory_map;
-
- // Parse stream directory entries
- llvm::ArrayRef<uint8_t> directory_data(
- data_sp->GetBytes() + directory_range.offset, directory_range.size);
- for (uint32_t i = 0; i < header->NumberOfStreams; ++i) {
- const Directory *directory_entry = nullptr;
- Status error = consumeObject(directory_data, directory_entry);
- if (error.Fail())
- return error.ToError();
- if (directory_entry->Type == StreamType::Unused) {
- // Ignore dummy streams (technically ill-formed, but a number of
- // existing minidumps seem to contain such streams)
- if (directory_entry->Location.DataSize == 0)
- continue;
- return stringError("invalid minidump: bad stream type");
- }
- // Update the streams map, checking for duplicate stream types
- if (!directory_map
- .insert({directory_entry->Type, directory_entry->Location})
- .second)
- return stringError("invalid minidump: duplicate stream type");
-
- // Ignore the zero-length streams for layout checks
- if (directory_entry->Location.DataSize != 0) {
- minidump_map.emplace_back(directory_entry->Location.RVA,
- directory_entry->Location.DataSize);
- }
- }
+ auto ExpectedFile = llvm::object::MinidumpFile::create(
+ llvm::MemoryBufferRef(toStringRef(data_sp->GetData()), "minidump"));
+ if (!ExpectedFile)
+ return ExpectedFile.takeError();
- // Sort the file map ranges by start offset
- llvm::sort(minidump_map.begin(), minidump_map.end(),
- [](const FileRange &a, const FileRange &b) {
- return a.offset < b.offset;
- });
-
- // Check for overlapping streams/data structures
- for (size_t i = 1; i < minidump_map.size(); ++i) {
- const auto &prev_range = minidump_map[i - 1];
- if (prev_range.end() > minidump_map[i].offset)
- return stringError("invalid minidump: overlapping streams");
- }
-
- // Check for streams past the end of file
- const auto &last_range = minidump_map.back();
- if (last_range.end() > file_size)
- return stringError("invalid minidump: truncated stream");
-
- return MinidumpParser(std::move(data_sp), std::move(directory_map));
+ return MinidumpParser(data_sp, std::move(*ExpectedFile));
}
-MinidumpParser::MinidumpParser(
- lldb::DataBufferSP data_sp,
- llvm::DenseMap<StreamType, LocationDescriptor> directory_map)
- : m_data_sp(std::move(data_sp)), m_directory_map(std::move(directory_map)) {
-}
+MinidumpParser::MinidumpParser(lldb::DataBufferSP data_sp,
+ std::unique_ptr<llvm::object::MinidumpFile> file)
+ : m_data_sp(std::move(data_sp)), m_file(std::move(file)) {}
llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(),
m_data_sp->GetByteSize());
}
-llvm::ArrayRef<uint8_t>
-MinidumpParser::GetStream(StreamType stream_type) {
- auto iter = m_directory_map.find(stream_type);
- if (iter == m_directory_map.end())
- return {};
-
- // check if there is enough data
- if (iter->second.RVA + iter->second.DataSize > m_data_sp->GetByteSize())
- return {};
-
- return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes() + iter->second.RVA,
- iter->second.DataSize);
+llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) {
+ return m_file->getRawStream(stream_type)
+ .getValueOr(llvm::ArrayRef<uint8_t>());
}
llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) {
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index 77207726675..07d7d07e599 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Minidump.h"
// C includes
@@ -93,20 +94,17 @@ public:
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
- const llvm::DenseMap<StreamType, LocationDescriptor> &
- GetDirectoryMap() const {
- return m_directory_map;
- }
+ llvm::object::MinidumpFile &GetMinidumpFile() { return *m_file; }
private:
MinidumpParser(lldb::DataBufferSP data_sp,
- llvm::DenseMap<StreamType, LocationDescriptor> directory_map);
+ std::unique_ptr<llvm::object::MinidumpFile> file);
MemoryRegionInfo FindMemoryRegion(lldb::addr_t load_addr) const;
private:
lldb::DataBufferSP m_data_sp;
- llvm::DenseMap<StreamType, LocationDescriptor> m_directory_map;
+ std::unique_ptr<llvm::object::MinidumpFile> m_file;
ArchSpec m_arch;
MemoryRegionInfos m_regions;
bool m_parsed_regions = false;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 4d16f82c493..d6ab58c0f05 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -718,10 +718,12 @@ public:
if (DumpDirectory()) {
s.Printf("RVA SIZE TYPE StreamType\n");
s.Printf("---------- ---------- ---------- --------------------------\n");
- for (const auto &pair: minidump.GetDirectoryMap())
- s.Printf("0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)pair.second.RVA,
- (uint32_t)pair.second.DataSize, (unsigned)pair.first,
- MinidumpParser::GetStreamTypeAsString(pair.first).data());
+ for (const auto &stream_desc : minidump.GetMinidumpFile().streams())
+ s.Printf(
+ "0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)stream_desc.Location.RVA,
+ (uint32_t)stream_desc.Location.DataSize,
+ (unsigned)(StreamType)stream_desc.Type,
+ MinidumpParser::GetStreamTypeAsString(stream_desc.Type).data());
s.Printf("\n");
}
auto DumpTextStream = [&](StreamType stream_type,
OpenPOWER on IntegriCloud