diff options
Diffstat (limited to 'lldb/source/Plugins/Process/minidump/MinidumpParser.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/minidump/MinidumpParser.cpp | 222 |
1 files changed, 108 insertions, 114 deletions
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index 18b8a3ff361..28dbd1bb5f1 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -1,4 +1,5 @@ -//===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===// +//===-- MinidumpParser.cpp ---------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -18,143 +19,136 @@ using namespace lldb_private; using namespace minidump; llvm::Optional<MinidumpParser> -MinidumpParser::Create(const lldb::DataBufferSP &data_buf_sp) -{ - if (data_buf_sp->GetByteSize() < sizeof(MinidumpHeader)) - { - return llvm::None; +MinidumpParser::Create(const lldb::DataBufferSP &data_buf_sp) { + if (data_buf_sp->GetByteSize() < sizeof(MinidumpHeader)) { + return llvm::None; + } + + llvm::ArrayRef<uint8_t> header_data(data_buf_sp->GetBytes(), + sizeof(MinidumpHeader)); + const MinidumpHeader *header = MinidumpHeader::Parse(header_data); + + if (header == nullptr) { + return llvm::None; + } + + lldb::offset_t directory_list_offset = header->stream_directory_rva; + // check if there is enough data for the parsing of the directory list + if ((directory_list_offset + + sizeof(MinidumpDirectory) * header->streams_count) > + data_buf_sp->GetByteSize()) { + return llvm::None; + } + + const MinidumpDirectory *directory = nullptr; + Error error; + llvm::ArrayRef<uint8_t> directory_data( + data_buf_sp->GetBytes() + directory_list_offset, + sizeof(MinidumpDirectory) * header->streams_count); + llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> directory_map; + + for (uint32_t i = 0; i < header->streams_count; ++i) { + error = consumeObject(directory_data, directory); + if (error.Fail()) { + return llvm::None; } + directory_map[static_cast<const uint32_t>(directory->stream_type)] = + directory->location; + } - llvm::ArrayRef<uint8_t> header_data(data_buf_sp->GetBytes(), sizeof(MinidumpHeader)); - const MinidumpHeader *header = MinidumpHeader::Parse(header_data); - - if (header == nullptr) - { - return llvm::None; - } - - lldb::offset_t directory_list_offset = header->stream_directory_rva; - // check if there is enough data for the parsing of the directory list - if ((directory_list_offset + sizeof(MinidumpDirectory) * header->streams_count) > data_buf_sp->GetByteSize()) - { - return llvm::None; - } - - const MinidumpDirectory *directory = nullptr; - Error error; - llvm::ArrayRef<uint8_t> directory_data(data_buf_sp->GetBytes() + directory_list_offset, - sizeof(MinidumpDirectory) * header->streams_count); - llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> directory_map; - - for (uint32_t i = 0; i < header->streams_count; ++i) - { - error = consumeObject(directory_data, directory); - if (error.Fail()) - { - return llvm::None; - } - directory_map[static_cast<const uint32_t>(directory->stream_type)] = directory->location; - } - - MinidumpParser parser(data_buf_sp, header, directory_map); - return llvm::Optional<MinidumpParser>(parser); + MinidumpParser parser(data_buf_sp, header, directory_map); + return llvm::Optional<MinidumpParser>(parser); } -MinidumpParser::MinidumpParser(const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header, - const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &directory_map) - : m_data_sp(data_buf_sp), m_header(header), m_directory_map(directory_map) -{ +MinidumpParser::MinidumpParser( + const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header, + const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &directory_map) + : m_data_sp(data_buf_sp), m_header(header), m_directory_map(directory_map) { } -lldb::offset_t -MinidumpParser::GetByteSize() -{ - return m_data_sp->GetByteSize(); +lldb::offset_t MinidumpParser::GetByteSize() { + return m_data_sp->GetByteSize(); } llvm::Optional<llvm::ArrayRef<uint8_t>> -MinidumpParser::GetStream(MinidumpStreamType stream_type) -{ - auto iter = m_directory_map.find(static_cast<uint32_t>(stream_type)); - if (iter == m_directory_map.end()) - return llvm::None; - - // check if there is enough data - if (iter->second.rva + iter->second.data_size > m_data_sp->GetByteSize()) - return llvm::None; - - llvm::ArrayRef<uint8_t> arr_ref(m_data_sp->GetBytes() + iter->second.rva, iter->second.data_size); - return llvm::Optional<llvm::ArrayRef<uint8_t>>(arr_ref); +MinidumpParser::GetStream(MinidumpStreamType stream_type) { + auto iter = m_directory_map.find(static_cast<uint32_t>(stream_type)); + if (iter == m_directory_map.end()) + return llvm::None; + + // check if there is enough data + if (iter->second.rva + iter->second.data_size > m_data_sp->GetByteSize()) + return llvm::None; + + llvm::ArrayRef<uint8_t> arr_ref(m_data_sp->GetBytes() + iter->second.rva, + iter->second.data_size); + return llvm::Optional<llvm::ArrayRef<uint8_t>>(arr_ref); } llvm::Optional<std::vector<const MinidumpThread *>> -MinidumpParser::GetThreads() -{ - llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::ThreadList); +MinidumpParser::GetThreads() { + llvm::Optional<llvm::ArrayRef<uint8_t>> data = + GetStream(MinidumpStreamType::ThreadList); - if (!data) - return llvm::None; + if (!data) + return llvm::None; - return MinidumpThread::ParseThreadList(data.getValue()); + return MinidumpThread::ParseThreadList(data.getValue()); } -const MinidumpSystemInfo * -MinidumpParser::GetSystemInfo() -{ - llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::SystemInfo); +const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() { + llvm::Optional<llvm::ArrayRef<uint8_t>> data = + GetStream(MinidumpStreamType::SystemInfo); - if (!data) - return nullptr; + if (!data) + return nullptr; - return MinidumpSystemInfo::Parse(data.getValue()); + return MinidumpSystemInfo::Parse(data.getValue()); } -ArchSpec -MinidumpParser::GetArchitecture() -{ - ArchSpec arch_spec; - arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); - arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); - arch_spec.GetTriple().setArch(llvm::Triple::ArchType::UnknownArch); - - // TODO should we add the OS type here, or somewhere else ? - - const MinidumpSystemInfo *system_info = GetSystemInfo(); - - if (!system_info) - return arch_spec; - - // TODO what to do about big endiand flavors of arm ? - // TODO set the arm subarch stuff if the minidump has info about it - - const MinidumpCPUArchitecture arch = - static_cast<const MinidumpCPUArchitecture>(static_cast<const uint32_t>(system_info->processor_arch)); - switch (arch) - { - case MinidumpCPUArchitecture::X86: - arch_spec.GetTriple().setArch(llvm::Triple::ArchType::x86); - break; - case MinidumpCPUArchitecture::AMD64: - arch_spec.GetTriple().setArch(llvm::Triple::ArchType::x86_64); - break; - case MinidumpCPUArchitecture::ARM: - arch_spec.GetTriple().setArch(llvm::Triple::ArchType::arm); - break; - case MinidumpCPUArchitecture::ARM64: - arch_spec.GetTriple().setArch(llvm::Triple::ArchType::aarch64); - break; - } +ArchSpec MinidumpParser::GetArchitecture() { + ArchSpec arch_spec; + arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); + arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); + arch_spec.GetTriple().setArch(llvm::Triple::ArchType::UnknownArch); + + // TODO should we add the OS type here, or somewhere else ? + const MinidumpSystemInfo *system_info = GetSystemInfo(); + + if (!system_info) return arch_spec; + + // TODO what to do about big endiand flavors of arm ? + // TODO set the arm subarch stuff if the minidump has info about it + + const MinidumpCPUArchitecture arch = + static_cast<const MinidumpCPUArchitecture>( + static_cast<const uint32_t>(system_info->processor_arch)); + switch (arch) { + case MinidumpCPUArchitecture::X86: + arch_spec.GetTriple().setArch(llvm::Triple::ArchType::x86); + break; + case MinidumpCPUArchitecture::AMD64: + arch_spec.GetTriple().setArch(llvm::Triple::ArchType::x86_64); + break; + case MinidumpCPUArchitecture::ARM: + arch_spec.GetTriple().setArch(llvm::Triple::ArchType::arm); + break; + case MinidumpCPUArchitecture::ARM64: + arch_spec.GetTriple().setArch(llvm::Triple::ArchType::aarch64); + break; + } + + return arch_spec; } -const MinidumpMiscInfo * -MinidumpParser::GetMiscInfo() -{ - llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::MiscInfo); +const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() { + llvm::Optional<llvm::ArrayRef<uint8_t>> data = + GetStream(MinidumpStreamType::MiscInfo); - if (!data) - return nullptr; + if (!data) + return nullptr; - return MinidumpMiscInfo::Parse(data.getValue()); + return MinidumpMiscInfo::Parse(data.getValue()); } |